adding integration opennebula-hosting app
This commit is contained in:
		
					parent
					
						
							
								2658205008
							
						
					
				
			
			
				commit
				
					
						ed806910e6
					
				
			
		
					 20 changed files with 641 additions and 239 deletions
				
			
		| 
						 | 
					@ -1,10 +1,13 @@
 | 
				
			||||||
 | 
					import random
 | 
				
			||||||
 | 
					import string
 | 
				
			||||||
from django import forms
 | 
					from django import forms
 | 
				
			||||||
from membership.models import CustomUser
 | 
					from membership.models import CustomUser
 | 
				
			||||||
from django.contrib.auth import authenticate
 | 
					from django.contrib.auth import authenticate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from utils.stripe_utils import StripeUtils
 | 
					from utils.stripe_utils import StripeUtils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .models import HostingOrder, VirtualMachinePlan
 | 
					from .models import HostingOrder, VirtualMachinePlan, UserHostingKey
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HostingOrderAdminForm(forms.ModelForm):
 | 
					class HostingOrderAdminForm(forms.ModelForm):
 | 
				
			||||||
| 
						 | 
					@ -83,3 +86,40 @@ class HostingUserSignupForm(forms.ModelForm):
 | 
				
			||||||
        if not confirm_password == password:
 | 
					        if not confirm_password == password:
 | 
				
			||||||
            raise forms.ValidationError("Passwords don't match")
 | 
					            raise forms.ValidationError("Passwords don't match")
 | 
				
			||||||
        return confirm_password
 | 
					        return confirm_password
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UserHostingKeyForm(forms.ModelForm):
 | 
				
			||||||
 | 
					    private_key = forms.CharField(widget=forms.PasswordInput(), required=False)
 | 
				
			||||||
 | 
					    public_key = forms.CharField(widget=forms.PasswordInput(), required=False)
 | 
				
			||||||
 | 
					    user = forms.models.ModelChoiceField(queryset=CustomUser.objects.all(), required=False)
 | 
				
			||||||
 | 
					    name = forms.CharField(required=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        self.request = kwargs.pop("request")
 | 
				
			||||||
 | 
					        super(UserHostingKeyForm, self).__init__(*args, **kwargs)
 | 
				
			||||||
 | 
					        # self.initial['user'].initial = self.request.user.id
 | 
				
			||||||
 | 
					        # print(self.fields)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clean_name(self):
 | 
				
			||||||
 | 
					        return ''.join(random.choice(string.ascii_lowercase) for i in range(7))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clean_user(self):
 | 
				
			||||||
 | 
					        return self.request.user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clean(self):
 | 
				
			||||||
 | 
					        cleaned_data = self.cleaned_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        print(cleaned_data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not cleaned_data.get('public_key'):
 | 
				
			||||||
 | 
					            private_key, public_key = UserHostingKey.generate_keys()
 | 
				
			||||||
 | 
					            cleaned_data.update({
 | 
				
			||||||
 | 
					                'private_key': private_key,
 | 
				
			||||||
 | 
					                'public_key': public_key
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return cleaned_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        model = UserHostingKey
 | 
				
			||||||
 | 
					        fields = ['user', 'public_key', 'name']
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,51 +7,100 @@ class Command(BaseCommand):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_data(self):
 | 
					    def get_data(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                'base_price': 10,
 | 
				
			||||||
 | 
					                'core_price': 5,
 | 
				
			||||||
 | 
					                'memory_price': 2,
 | 
				
			||||||
 | 
					                'disk_size_price': 0.6,
 | 
				
			||||||
 | 
					                'cores': 1,
 | 
				
			||||||
 | 
					                'memory': 2,
 | 
				
			||||||
 | 
					                'disk_size': 10
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                'base_price': 10,
 | 
				
			||||||
 | 
					                'core_price': 5,
 | 
				
			||||||
 | 
					                'memory_price': 2,
 | 
				
			||||||
 | 
					                'disk_size_price': 0.6,
 | 
				
			||||||
 | 
					                'cores': 1,
 | 
				
			||||||
 | 
					                'memory': 2,
 | 
				
			||||||
 | 
					                'disk_size': 100
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                'base_price': 10,
 | 
				
			||||||
 | 
					                'core_price': 5,
 | 
				
			||||||
 | 
					                'memory_price': 2,
 | 
				
			||||||
 | 
					                'disk_size_price': 0.6,
 | 
				
			||||||
 | 
					                'cores': 2,
 | 
				
			||||||
 | 
					                'memory': 4,
 | 
				
			||||||
 | 
					                'disk_size': 20
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                'base_price': 10,
 | 
				
			||||||
 | 
					                'core_price': 5,
 | 
				
			||||||
 | 
					                'memory_price': 2,
 | 
				
			||||||
 | 
					                'disk_size_price': 0.6,
 | 
				
			||||||
 | 
					                'cores': 4,
 | 
				
			||||||
 | 
					                'memory': 8,
 | 
				
			||||||
 | 
					                'disk_size': 40
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                'base_price': 10,
 | 
				
			||||||
 | 
					                'core_price': 5,
 | 
				
			||||||
 | 
					                'memory_price': 2,
 | 
				
			||||||
 | 
					                'disk_size_price': 0.6,
 | 
				
			||||||
 | 
					                'cores': 16,
 | 
				
			||||||
 | 
					                'memory': 8,
 | 
				
			||||||
 | 
					                'disk_size': 40
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        hetzner = {
 | 
					        hetzner = {
 | 
				
			||||||
            'base_price': 10,
 | 
					            'base_price': 10,
 | 
				
			||||||
            'core_price': 10,
 | 
					            'core_price': 5,
 | 
				
			||||||
            'memory_price': 5,
 | 
					            'memory_price': 2,
 | 
				
			||||||
            'disk_size_price': 1,
 | 
					            'disk_size_price': 0.6,
 | 
				
			||||||
            'description': 'VM auf einzelner HW, Raid1, kein HA',
 | 
					            'description': 'VM auf einzelner HW, Raid1, kein HA',
 | 
				
			||||||
            'location': 'DE'
 | 
					            'location': 'DE'
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return {
 | 
					        # return {
 | 
				
			||||||
            # 'hetzner_nug': {
 | 
					        #     # 'hetzner_nug': {
 | 
				
			||||||
            #     'base_price': 5,
 | 
					        #     #     'base_price': 5,
 | 
				
			||||||
            #     'memory_price': 2,
 | 
					        #     #     'memory_price': 2,
 | 
				
			||||||
            #     'core_price': 2,
 | 
					        #     #     'core_price': 2,
 | 
				
			||||||
            #     'disk_size_price': 0.5,
 | 
					        #     #     'disk_size_price': 0.5,
 | 
				
			||||||
            #     'description': 'VM ohne Uptime Garantie'
 | 
					        #     #     'description': 'VM ohne Uptime Garantie'
 | 
				
			||||||
            # },
 | 
					        #     # },
 | 
				
			||||||
            'hetzner': hetzner,
 | 
					        #     'hetzner': hetzner,
 | 
				
			||||||
            # 'hetzner_raid6': {
 | 
					        #     # 'hetzner_raid6': {
 | 
				
			||||||
            #     'base_price': hetzner['base_price']*1.2,
 | 
					        #     #     'base_price': hetzner['base_price']*1.2,
 | 
				
			||||||
            #     'core_price': hetzner['core_price']*1.2,
 | 
					        #     #     'core_price': hetzner['core_price']*1.2,
 | 
				
			||||||
            #     'memory_price': hetzner['memory_price']*1.2,
 | 
					        #     #     'memory_price': hetzner['memory_price']*1.2,
 | 
				
			||||||
            #     'disk_size_price': hetzner['disk_size_price']*1.2,
 | 
					        #     #     'disk_size_price': hetzner['disk_size_price']*1.2,
 | 
				
			||||||
            #     'description': 'VM auf einzelner HW, Raid1, kein HA'
 | 
					        #     #     'description': 'VM auf einzelner HW, Raid1, kein HA'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # },
 | 
					        #     # },
 | 
				
			||||||
            # 'hetzner_glusterfs': {
 | 
					        #     # 'hetzner_glusterfs': {
 | 
				
			||||||
            #     'base_price': hetzner['base_price']*1.4,
 | 
					        #     #     'base_price': hetzner['base_price']*1.4,
 | 
				
			||||||
            #     'core_price': hetzner['core_price']*1.4,
 | 
					        #     #     'core_price': hetzner['core_price']*1.4,
 | 
				
			||||||
            #     'memory_price': hetzner['memory_price']*1.4,
 | 
					        #     #     'memory_price': hetzner['memory_price']*1.4,
 | 
				
			||||||
            #     'disk_size_price': hetzner['disk_size_price']*1.4,
 | 
					        #     #     'disk_size_price': hetzner['disk_size_price']*1.4,
 | 
				
			||||||
            #     'description': 'VM auf einzelner HW, Raid1, kein HA'
 | 
					        #     #     'description': 'VM auf einzelner HW, Raid1, kein HA'
 | 
				
			||||||
            # },
 | 
					        #     # },
 | 
				
			||||||
            'bern': {
 | 
					        #     'bern': {
 | 
				
			||||||
                'base_price': 12,
 | 
					        #         'base_price': 12,
 | 
				
			||||||
                'core_price': 25,
 | 
					        #         'core_price': 25,
 | 
				
			||||||
                'memory_price': 7,
 | 
					        #         'memory_price': 7,
 | 
				
			||||||
                'disk_size_price': 0.70,
 | 
					        #         'disk_size_price': 0.70,
 | 
				
			||||||
                'description': "VM in Bern, HA Setup ohne HA Garantie",
 | 
					        #         'description': "VM in Bern, HA Setup ohne HA Garantie",
 | 
				
			||||||
                'location': 'CH',
 | 
					        #         'location': 'CH',
 | 
				
			||||||
            }
 | 
					        #     }
 | 
				
			||||||
        }
 | 
					        # }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle(self, *args, **options):
 | 
					    def handle(self, *args, **options):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        data = self.get_data()
 | 
					        vm_data = self.get_data()
 | 
				
			||||||
        [VirtualMachineType.objects.create(hosting_company=key, **data[key])
 | 
					        for vm in vm_data:
 | 
				
			||||||
            for key in data.keys()]
 | 
					            VirtualMachineType.objects.create(**vm)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										35
									
								
								hosting/migrations/0028_managevm_userhostingkey.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								hosting/migrations/0028_managevm_userhostingkey.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					# Generated by Django 1.9.4 on 2017-04-29 18:28
 | 
				
			||||||
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.conf import settings
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					import django.db.models.deletion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
 | 
				
			||||||
 | 
					        ('hosting', '0027_auto_20160711_0210'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.CreateModel(
 | 
				
			||||||
 | 
					            name='ManageVM',
 | 
				
			||||||
 | 
					            fields=[
 | 
				
			||||||
 | 
					                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            options={
 | 
				
			||||||
 | 
					                'managed': False,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.CreateModel(
 | 
				
			||||||
 | 
					            name='UserHostingKey',
 | 
				
			||||||
 | 
					            fields=[
 | 
				
			||||||
 | 
					                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
				
			||||||
 | 
					                ('public_key', models.TextField()),
 | 
				
			||||||
 | 
					                ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										23
									
								
								hosting/migrations/0029_userhostingkey_created_at.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								hosting/migrations/0029_userhostingkey_created_at.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					# Generated by Django 1.9.4 on 2017-04-30 19:04
 | 
				
			||||||
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import datetime
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					from django.utils.timezone import utc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('hosting', '0028_managevm_userhostingkey'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='userhostingkey',
 | 
				
			||||||
 | 
					            name='created_at',
 | 
				
			||||||
 | 
					            field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2017, 4, 30, 19, 4, 20, 780173, tzinfo=utc)),
 | 
				
			||||||
 | 
					            preserve_default=False,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										21
									
								
								hosting/migrations/0030_userhostingkey_name.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								hosting/migrations/0030_userhostingkey_name.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					# Generated by Django 1.9.4 on 2017-04-30 19:09
 | 
				
			||||||
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('hosting', '0029_userhostingkey_created_at'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='userhostingkey',
 | 
				
			||||||
 | 
					            name='name',
 | 
				
			||||||
 | 
					            field=models.CharField(default='', max_length=100),
 | 
				
			||||||
 | 
					            preserve_default=False,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										23
									
								
								hosting/migrations/0031_auto_20170503_0554.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								hosting/migrations/0031_auto_20170503_0554.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					# Generated by Django 1.9.4 on 2017-05-03 05:54
 | 
				
			||||||
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('hosting', '0030_userhostingkey_name'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.RemoveField(
 | 
				
			||||||
 | 
					            model_name='virtualmachinetype',
 | 
				
			||||||
 | 
					            name='hosting_company',
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.RemoveField(
 | 
				
			||||||
 | 
					            model_name='virtualmachinetype',
 | 
				
			||||||
 | 
					            name='location',
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										33
									
								
								hosting/migrations/0032_auto_20170504_0315.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								hosting/migrations/0032_auto_20170504_0315.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					# Generated by Django 1.9.4 on 2017-05-04 03:15
 | 
				
			||||||
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('hosting', '0031_auto_20170503_0554'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='virtualmachinetype',
 | 
				
			||||||
 | 
					            name='cores',
 | 
				
			||||||
 | 
					            field=models.IntegerField(default=0),
 | 
				
			||||||
 | 
					            preserve_default=False,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='virtualmachinetype',
 | 
				
			||||||
 | 
					            name='disk_size',
 | 
				
			||||||
 | 
					            field=models.IntegerField(default=0),
 | 
				
			||||||
 | 
					            preserve_default=False,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='virtualmachinetype',
 | 
				
			||||||
 | 
					            name='memory',
 | 
				
			||||||
 | 
					            field=models.IntegerField(default=0),
 | 
				
			||||||
 | 
					            preserve_default=False,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										20
									
								
								hosting/migrations/0033_virtualmachinetype_configuration.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								hosting/migrations/0033_virtualmachinetype_configuration.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					# Generated by Django 1.9.4 on 2017-05-04 03:23
 | 
				
			||||||
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('hosting', '0032_auto_20170504_0315'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='virtualmachinetype',
 | 
				
			||||||
 | 
					            name='configuration',
 | 
				
			||||||
 | 
					            field=models.CharField(choices=[('debian', 'Debian 8'), ('ubuntu', 'Ubuntu 16.06'), ('devuan', 'Devuan 1'), ('centos', 'CentOS 7')], default='ubuntu', max_length=10),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										30
									
								
								hosting/migrations/0034_auto_20170504_0331.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								hosting/migrations/0034_auto_20170504_0331.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,30 @@
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					# Generated by Django 1.9.4 on 2017-05-04 03:31
 | 
				
			||||||
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					import django.db.models.deletion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('hosting', '0033_virtualmachinetype_configuration'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.RemoveField(
 | 
				
			||||||
 | 
					            model_name='virtualmachinetype',
 | 
				
			||||||
 | 
					            name='configuration',
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='virtualmachineplan',
 | 
				
			||||||
 | 
					            name='configuration',
 | 
				
			||||||
 | 
					            field=models.CharField(choices=[('debian', 'Debian 8'), ('ubuntu', 'Ubuntu 16.06'), ('devuan', 'Devuan 1'), ('centos', 'CentOS 7')], max_length=20),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='virtualmachineplan',
 | 
				
			||||||
 | 
					            name='vm_type',
 | 
				
			||||||
 | 
					            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='hosting.VirtualMachineType'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
| 
						 | 
					@ -1,23 +1,32 @@
 | 
				
			||||||
from django.shortcuts import redirect
 | 
					from django.shortcuts import redirect
 | 
				
			||||||
from django.core.urlresolvers import reverse
 | 
					from django.core.urlresolvers import reverse
 | 
				
			||||||
from .models import VirtualMachinePlan
 | 
					from .models import VirtualMachinePlan, VirtualMachineType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ProcessVMSelectionMixin(object):
 | 
					class ProcessVMSelectionMixin(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def post(self, request, *args, **kwargs):
 | 
					    def post(self, request, *args, **kwargs):
 | 
				
			||||||
        hosting = request.POST.get('configuration')
 | 
					        configuration = request.POST.get('configuration')
 | 
				
			||||||
        configuration_detail = dict(VirtualMachinePlan.VM_CONFIGURATION).get(hosting)
 | 
					        configuration_display = dict(VirtualMachinePlan.VM_CONFIGURATION).get(configuration)
 | 
				
			||||||
        vm_specs = {
 | 
					        vm_template = request.POST.get('vm_template')
 | 
				
			||||||
            'cores': request.POST.get('cores'),
 | 
					        vm_type = VirtualMachineType.objects.get(id=vm_template)
 | 
				
			||||||
            'memory': request.POST.get('memory'),
 | 
					        vm_specs = vm_type.get_specs()
 | 
				
			||||||
            'disk_size': request.POST.get('disk_space'),
 | 
					        vm_specs.update({
 | 
				
			||||||
            'hosting_company': request.POST.get('hosting_company'),
 | 
					            'configuration_display': configuration_display,
 | 
				
			||||||
            'location_code': request.POST.get('location_code'),
 | 
					            'configuration': configuration,
 | 
				
			||||||
            'configuration': hosting,
 | 
					            'final_price': vm_type.final_price,
 | 
				
			||||||
            'configuration_detail': configuration_detail,
 | 
					            'vm_template': vm_template
 | 
				
			||||||
            'final_price': request.POST.get('final_price')
 | 
					        })
 | 
				
			||||||
        }
 | 
					        # vm_specs = {
 | 
				
			||||||
 | 
					        #     # 'cores': request.POST.get('cores'),
 | 
				
			||||||
 | 
					        #     # 'memory': request.POST.get('memory'),
 | 
				
			||||||
 | 
					        #     # 'disk_size': request.POST.get('disk_space'),
 | 
				
			||||||
 | 
					        #     # 'hosting_company': request.POST.get('hosting_company'),
 | 
				
			||||||
 | 
					        #     # 'location_code': request.POST.get('location_code'),
 | 
				
			||||||
 | 
					        #     # 'configuration': hosting,
 | 
				
			||||||
 | 
					        #     # 'configuration_detail': configuration_detail,
 | 
				
			||||||
 | 
					        #     'final_price': request.POST.get('final_price')
 | 
				
			||||||
 | 
					        # }
 | 
				
			||||||
        request.session['vm_specs'] = vm_specs
 | 
					        request.session['vm_specs'] = vm_specs
 | 
				
			||||||
        if not request.user.is_authenticated():
 | 
					        if not request.user.is_authenticated():
 | 
				
			||||||
            request.session['vm_specs'] = vm_specs
 | 
					            request.session['vm_specs'] = vm_specs
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,7 @@ from django.utils.functional import cached_property
 | 
				
			||||||
from Crypto.PublicKey import RSA
 | 
					from Crypto.PublicKey import RSA
 | 
				
			||||||
from stored_messages.settings import stored_messages_settings
 | 
					from stored_messages.settings import stored_messages_settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from membership.models import StripeCustomer
 | 
					from membership.models import StripeCustomer, CustomUser
 | 
				
			||||||
from utils.models import BillingAddress
 | 
					from utils.models import BillingAddress
 | 
				
			||||||
from utils.mixins import AssignPermissionsMixin
 | 
					from utils.mixins import AssignPermissionsMixin
 | 
				
			||||||
from .managers import VMPlansManager
 | 
					from .managers import VMPlansManager
 | 
				
			||||||
| 
						 | 
					@ -15,88 +15,71 @@ from .managers import VMPlansManager
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VirtualMachineType(models.Model):
 | 
					class VirtualMachineType(models.Model):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    BASE_PRICE = 0.5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    HETZNER_NUG = 'hetzner_nug'
 | 
					 | 
				
			||||||
    HETZNER = 'hetzner'
 | 
					 | 
				
			||||||
    HETZNER_R6 = 'hetzner_raid6'
 | 
					 | 
				
			||||||
    HETZNER_G = 'hetzner_glusterfs'
 | 
					 | 
				
			||||||
    BERN = 'bern'
 | 
					 | 
				
			||||||
    DE_LOCATION = 'DE'
 | 
					 | 
				
			||||||
    CH_LOCATION = 'CH'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    HOSTING_TYPES = (
 | 
					 | 
				
			||||||
        (HETZNER_NUG, 'Hetzner No Uptime Guarantee'),
 | 
					 | 
				
			||||||
        (HETZNER, 'Hetzner'),
 | 
					 | 
				
			||||||
        (HETZNER_R6, 'Hetzner Raid6'),
 | 
					 | 
				
			||||||
        (HETZNER_G, 'Hetzner Glusterfs'),
 | 
					 | 
				
			||||||
        (BERN, 'Bern'),
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    LOCATIONS_CHOICES = (
 | 
					 | 
				
			||||||
        (DE_LOCATION, 'Germany'),
 | 
					 | 
				
			||||||
        (CH_LOCATION, 'Switzerland'),
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    description = models.TextField()
 | 
					    description = models.TextField()
 | 
				
			||||||
    base_price = models.FloatField()
 | 
					    base_price = models.FloatField()
 | 
				
			||||||
    memory_price = models.FloatField()
 | 
					    memory_price = models.FloatField()
 | 
				
			||||||
    core_price = models.FloatField()
 | 
					    core_price = models.FloatField()
 | 
				
			||||||
    disk_size_price = models.FloatField()
 | 
					    disk_size_price = models.FloatField()
 | 
				
			||||||
    hosting_company = models.CharField(max_length=30, choices=HOSTING_TYPES)
 | 
					    cores = models.IntegerField()
 | 
				
			||||||
    location = models.CharField(max_length=3, choices=LOCATIONS_CHOICES)
 | 
					    memory = models.IntegerField()
 | 
				
			||||||
 | 
					    disk_size = models.IntegerField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return "%s" % (self.get_hosting_company_display())
 | 
					        return "VM Type %s" % (self.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @cached_property
 | 
				
			||||||
 | 
					    def final_price(self):
 | 
				
			||||||
 | 
					        price = self.cores * self.core_price
 | 
				
			||||||
 | 
					        price += self.memory * self.memory_price
 | 
				
			||||||
 | 
					        price += self.disk_size * self.disk_size_price
 | 
				
			||||||
 | 
					        return price
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def get_serialized_vm_types(cls):
 | 
					    def get_serialized_vm_types(cls):
 | 
				
			||||||
        return [vm.get_serialized_data()
 | 
					        return [vm.get_serialized_data()
 | 
				
			||||||
                for vm in cls.objects.all()]
 | 
					                for vm in cls.objects.all()]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # def calculate_price(self, specifications):
 | 
					    def calculate_price(self):
 | 
				
			||||||
    #     price = float(specifications['cores']) * self.core_price
 | 
					        price = self.cores * self.core_price
 | 
				
			||||||
    #     price += float(specifications['memory']) * self.memory_price
 | 
					        price += self.memory * self.memory_price
 | 
				
			||||||
    #     price += float(specifications['disk_size']) * self.disk_size_price
 | 
					        price += self.disk_size * self.disk_size_price
 | 
				
			||||||
        # price += self.base_price
 | 
					        # price += self.base_price
 | 
				
			||||||
    #     return price
 | 
					        return price
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    # @classmethod
 | 
				
			||||||
    def get_price(cls, vm_template):
 | 
					    # def get_price(cls, vm_template):
 | 
				
			||||||
        return cls.BASE_PRICE * vm_template
 | 
					    #     return cls.BASE_PRICE * vm_template
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    def get_specs(self):
 | 
				
			||||||
    def get_specs(cls, vm_template):
 | 
					 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            'memory': 1024 * vm_template,
 | 
					            'memory': self.memory,
 | 
				
			||||||
            'cores': 0.1 * vm_template,
 | 
					            'cores': self.cores,
 | 
				
			||||||
            'disk_size': 10000 * vm_template
 | 
					            'disk_size': self.disk_size
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def calculate_price(self, vm_template):
 | 
					    # def calculate_price(self, vm_template):
 | 
				
			||||||
        price = self.base_price * vm_template
 | 
					    #     price = self.base_price * vm_template
 | 
				
			||||||
        return price
 | 
					    #     return price
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def defeault_price(self):
 | 
					    # def defeault_price(self):
 | 
				
			||||||
        price = self.base_price
 | 
					    #     price = self.base_price
 | 
				
			||||||
        price += self.core_price
 | 
					    #     price += self.core_price
 | 
				
			||||||
        price += self.memory_price
 | 
					    #     price += self.memory_price
 | 
				
			||||||
        price += self.disk_size_price * 10
 | 
					    #     price += self.disk_size_price * 10
 | 
				
			||||||
        return price
 | 
					    #     return price
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_serialized_data(self):
 | 
					    def get_serialized_data(self):
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            'description': self.description,
 | 
					            'description': self.description,
 | 
				
			||||||
            'base_price': self.base_price,
 | 
					 | 
				
			||||||
            'core_price': self.core_price,
 | 
					            'core_price': self.core_price,
 | 
				
			||||||
            'disk_size_price': self.disk_size_price,
 | 
					            'disk_size_price': self.disk_size_price,
 | 
				
			||||||
            'memory_price': self.memory_price,
 | 
					            'memory_price': self.memory_price,
 | 
				
			||||||
            'hosting_company_name': self.get_hosting_company_display(),
 | 
					 | 
				
			||||||
            'hosting_company': self.hosting_company,
 | 
					 | 
				
			||||||
            'default_price': self.defeault_price(),
 | 
					 | 
				
			||||||
            'location_code': self.location,
 | 
					 | 
				
			||||||
            'location': self.get_location_display(),
 | 
					 | 
				
			||||||
            'id': self.id,
 | 
					            'id': self.id,
 | 
				
			||||||
 | 
					            'final_price': self.final_price,
 | 
				
			||||||
 | 
					            'cores': self.cores,
 | 
				
			||||||
 | 
					            'memory': self.memory,
 | 
				
			||||||
 | 
					            'disk_size': self.disk_size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,14 +95,21 @@ class VirtualMachinePlan(AssignPermissionsMixin, models.Model):
 | 
				
			||||||
        (CANCELED_STATUS, 'Canceled')
 | 
					        (CANCELED_STATUS, 'Canceled')
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DJANGO = 'django'
 | 
					    # DJANGO = 'django'
 | 
				
			||||||
    RAILS = 'rails'
 | 
					    # RAILS = 'rails'
 | 
				
			||||||
    NODEJS = 'nodejs'
 | 
					    # NODEJS = 'nodejs'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # VM_CONFIGURATION = (
 | 
				
			||||||
 | 
					    #     (DJANGO, 'Ubuntu 14.04, Django'),
 | 
				
			||||||
 | 
					    #     (RAILS, 'Ubuntu 14.04, Rails'),
 | 
				
			||||||
 | 
					    #     (NODEJS, 'Debian, NodeJS'),
 | 
				
			||||||
 | 
					    # )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    VM_CONFIGURATION = (
 | 
					    VM_CONFIGURATION = (
 | 
				
			||||||
        (DJANGO, 'Ubuntu 14.04, Django'),
 | 
					        ('debian', 'Debian 8'),
 | 
				
			||||||
        (RAILS, 'Ubuntu 14.04, Rails'),
 | 
					        ('ubuntu', 'Ubuntu 16.06'),
 | 
				
			||||||
        (NODEJS, 'Debian, NodeJS'),
 | 
					        ('devuan', 'Devuan 1'),
 | 
				
			||||||
 | 
					        ('centos', 'CentOS 7')
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    permissions = ('view_virtualmachineplan',
 | 
					    permissions = ('view_virtualmachineplan',
 | 
				
			||||||
| 
						 | 
					@ -129,7 +119,7 @@ class VirtualMachinePlan(AssignPermissionsMixin, models.Model):
 | 
				
			||||||
    cores = models.IntegerField()
 | 
					    cores = models.IntegerField()
 | 
				
			||||||
    memory = models.IntegerField()
 | 
					    memory = models.IntegerField()
 | 
				
			||||||
    disk_size = models.IntegerField()
 | 
					    disk_size = models.IntegerField()
 | 
				
			||||||
    vm_type = models.ForeignKey(VirtualMachineType)
 | 
					    vm_type = models.ForeignKey(VirtualMachineType, null=True)
 | 
				
			||||||
    price = models.FloatField()
 | 
					    price = models.FloatField()
 | 
				
			||||||
    public_key = models.TextField(blank=True)
 | 
					    public_key = models.TextField(blank=True)
 | 
				
			||||||
    status = models.CharField(max_length=20, choices=VM_STATUS_CHOICES, default=PENDING_STATUS)
 | 
					    status = models.CharField(max_length=20, choices=VM_STATUS_CHOICES, default=PENDING_STATUS)
 | 
				
			||||||
| 
						 | 
					@ -147,13 +137,13 @@ class VirtualMachinePlan(AssignPermissionsMixin, models.Model):
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return self.name
 | 
					        return self.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @cached_property
 | 
					    # @cached_property
 | 
				
			||||||
    def hosting_company_name(self):
 | 
					    # def hosting_company_name(self):
 | 
				
			||||||
        return self.vm_type.get_hosting_company_display()
 | 
					    #     return self.vm_type.get_hosting_company_display()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @cached_property
 | 
					    # @cached_property
 | 
				
			||||||
    def location(self):
 | 
					    # def location(self):
 | 
				
			||||||
        return self.vm_type.get_location_display()
 | 
					    #     return self.vm_type.get_location_display()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @cached_property
 | 
					    @cached_property
 | 
				
			||||||
    def name(self):
 | 
					    def name(self):
 | 
				
			||||||
| 
						 | 
					@ -173,24 +163,6 @@ class VirtualMachinePlan(AssignPermissionsMixin, models.Model):
 | 
				
			||||||
        instance.assign_permissions(user)
 | 
					        instance.assign_permissions(user)
 | 
				
			||||||
        return instance
 | 
					        return instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @staticmethod
 | 
					 | 
				
			||||||
    def generate_RSA(bits=2048):
 | 
					 | 
				
			||||||
        '''
 | 
					 | 
				
			||||||
        Generate an RSA keypair with an exponent of 65537 in PEM format
 | 
					 | 
				
			||||||
        param: bits The key length in bits
 | 
					 | 
				
			||||||
        Return private key and public key
 | 
					 | 
				
			||||||
        '''
 | 
					 | 
				
			||||||
        new_key = RSA.generate(2048, os.urandom)
 | 
					 | 
				
			||||||
        public_key = new_key.publickey().exportKey("OpenSSH")
 | 
					 | 
				
			||||||
        private_key = new_key.exportKey("PEM")
 | 
					 | 
				
			||||||
        return private_key, public_key
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def generate_keys(self):
 | 
					 | 
				
			||||||
        private_key, public_key = self.generate_RSA()
 | 
					 | 
				
			||||||
        self.public_key = public_key
 | 
					 | 
				
			||||||
        self.save(update_fields=['public_key'])
 | 
					 | 
				
			||||||
        return private_key, public_key
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def cancel_plan(self):
 | 
					    def cancel_plan(self):
 | 
				
			||||||
        self.status = self.CANCELED_STATUS
 | 
					        self.status = self.CANCELED_STATUS
 | 
				
			||||||
        self.save(update_fields=['status'])
 | 
					        self.save(update_fields=['status'])
 | 
				
			||||||
| 
						 | 
					@ -242,6 +214,32 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
 | 
				
			||||||
        self.save()
 | 
					        self.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UserHostingKey(models.Model):
 | 
				
			||||||
 | 
					    user = models.ForeignKey(CustomUser)
 | 
				
			||||||
 | 
					    public_key = models.TextField()
 | 
				
			||||||
 | 
					    created_at = models.DateTimeField(auto_now_add=True)
 | 
				
			||||||
 | 
					    name = models.CharField(max_length=100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @staticmethod
 | 
				
			||||||
 | 
					    def generate_RSA(bits=2048):
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					        Generate an RSA keypair with an exponent of 65537 in PEM format
 | 
				
			||||||
 | 
					        param: bits The key length in bits
 | 
				
			||||||
 | 
					        Return private key and public key
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					        new_key = RSA.generate(2048, os.urandom)
 | 
				
			||||||
 | 
					        public_key = new_key.publickey().exportKey("OpenSSH")
 | 
				
			||||||
 | 
					        private_key = new_key.exportKey("PEM")
 | 
				
			||||||
 | 
					        return private_key, public_key
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def generate_keys(cls):
 | 
				
			||||||
 | 
					        private_key, public_key = cls.generate_RSA()
 | 
				
			||||||
 | 
					        # self.public_key = public_key
 | 
				
			||||||
 | 
					        # self.save(update_fields=['public_key'])
 | 
				
			||||||
 | 
					        return private_key, public_key
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ManageVM(models.Model):
 | 
					class ManageVM(models.Model):
 | 
				
			||||||
    def has_add_permission(self, request):
 | 
					    def has_add_permission(self, request):
 | 
				
			||||||
        return False
 | 
					        return False
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,6 +72,11 @@
 | 
				
			||||||
                                <i class="fa fa-credit-card"></i> {% trans "My Orders"%}
 | 
					                                <i class="fa fa-credit-card"></i> {% trans "My Orders"%}
 | 
				
			||||||
                            </a>
 | 
					                            </a>
 | 
				
			||||||
                        </li>
 | 
					                        </li>
 | 
				
			||||||
 | 
					                        <li>
 | 
				
			||||||
 | 
					                            <a href="{% url 'hosting:key_pair' %}">
 | 
				
			||||||
 | 
					                                <i class="fa fa-key" aria-hidden="true"></i> {% trans "Keys"%}
 | 
				
			||||||
 | 
					                            </a>
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
                        <li>
 | 
					                        <li>
 | 
				
			||||||
                            <a href="{% url 'hosting:notifications' %}">
 | 
					                            <a href="{% url 'hosting:notifications' %}">
 | 
				
			||||||
                                <i class="fa fa-bell"></i> {% trans "Notifications "%}
 | 
					                                <i class="fa fa-bell"></i> {% trans "Notifications "%}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										45
									
								
								hosting/templates/hosting/create_virtual_machine.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								hosting/templates/hosting/create_virtual_machine.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,45 @@
 | 
				
			||||||
 | 
					{% extends "hosting/base_short.html" %}
 | 
				
			||||||
 | 
					{% load staticfiles bootstrap3 i18n %}
 | 
				
			||||||
 | 
					{% block content %} 
 | 
				
			||||||
 | 
					<div>
 | 
				
			||||||
 | 
					    <div class="container dashboard-container">
 | 
				
			||||||
 | 
					        <div class="row">
 | 
				
			||||||
 | 
					            <div class="col-md-8 col-md-offset-2">
 | 
				
			||||||
 | 
					                <h3><i class="fa fa-server" aria-hidden="true"></i> {% trans "New Virtual Machine"%} </h3>
 | 
				
			||||||
 | 
					                <hr/>
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                <form  method="POST" action="">
 | 
				
			||||||
 | 
					                    {% csrf_token %}
 | 
				
			||||||
 | 
					                    <div class="form-group">
 | 
				
			||||||
 | 
					                        Select VM Type:
 | 
				
			||||||
 | 
					                        <select name="vm_template">
 | 
				
			||||||
 | 
					                            {% for vm in vm_types %}
 | 
				
			||||||
 | 
					                               
 | 
				
			||||||
 | 
					                                  <option value="{{vm.id}}">CORE: {{vm.cores}}- RAM: {{vm.memory}} - SSD: {{vm.disk_size}}  </option>
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                            {% endfor %}
 | 
				
			||||||
 | 
					                        </select>
 | 
				
			||||||
 | 
					                    </div> 
 | 
				
			||||||
 | 
					                    <div class="form-group">
 | 
				
			||||||
 | 
					                        Select VM Configuration:
 | 
				
			||||||
 | 
					                        <select name="configuration">
 | 
				
			||||||
 | 
					                            {% for config in configuration_options %}
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                                <option value="{{config.0}}">{{config.1}} </option>
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                            {% endfor %}
 | 
				
			||||||
 | 
					                        </select>
 | 
				
			||||||
 | 
					                    </div>                          
 | 
				
			||||||
 | 
					                    <div class="form-group">
 | 
				
			||||||
 | 
					                        <button class="btn btn-success" >{% trans "Start VM"%} </button>                         
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{%endblock%}
 | 
				
			||||||
| 
						 | 
					@ -24,59 +24,17 @@
 | 
				
			||||||
                {% csrf_token %}
 | 
					                {% csrf_token %}
 | 
				
			||||||
                <input type="hidden" name="hosting_company" value="{{vm.hosting_company}}">
 | 
					                <input type="hidden" name="hosting_company" value="{{vm.hosting_company}}">
 | 
				
			||||||
                <input type="hidden" name="location_code" value="{{vm.location_code}}">
 | 
					                <input type="hidden" name="location_code" value="{{vm.location_code}}">
 | 
				
			||||||
                <input type="hidden" name="vm_template" value="1">
 | 
					                <input type="hidden" name="vm_template" value="{{vm.id}}">
 | 
				
			||||||
               
 | 
					               
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                <ul class="pricing {% cycle 'p-red' 'p-black' 'p-red' 'p-yel' %}">
 | 
					                <ul class="pricing {% cycle 'p-red' 'p-black' 'p-red' 'p-yel' %}">
 | 
				
			||||||
                  <li class="type">
 | 
					 | 
				
			||||||
                    <!-- <img src="http://bread.pp.ua/n/settings_g.svg" alt=""> -->
 | 
					 | 
				
			||||||
                    <h3 >{{vm.location_code}}</h3>
 | 
					 | 
				
			||||||
                    <br/>
 | 
					 | 
				
			||||||
                    <img class="img-responsive" src="{{ STATIC_URL }}hosting/img/{{vm.location_code}}_flag.png" alt="">
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                  </li>
 | 
					 | 
				
			||||||
                  <li>
 | 
					                  <li>
 | 
				
			||||||
                    <!-- Single button -->
 | 
					                    <!-- Single button -->
 | 
				
			||||||
                    <div class="btn-group">
 | 
					                    <div class="btn-group">
 | 
				
			||||||
                      <div class="form-group">
 | 
					                      <div class="form-group">
 | 
				
			||||||
                        <label for="cores">Location: </label>
 | 
					                        <label for="cores">Cores: {{vm.cores}}</label> 
 | 
				
			||||||
                        {{vm.location}}
 | 
					 | 
				
			||||||
                      </div>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                  </li>
 | 
					 | 
				
			||||||
                  <li>
 | 
					 | 
				
			||||||
                  <label for="configuration">Configuration: </label>
 | 
					 | 
				
			||||||
                    {% if select_configuration %}
 | 
					 | 
				
			||||||
                        <select class="form-control" name="configuration" id="{{vm.hosting_company}}-configuration" data-vm-type="{{vm.hosting_company}}">
 | 
					 | 
				
			||||||
                        {% for key,value in configuration_options.items   %}
 | 
					 | 
				
			||||||
                            <option  value="{{key}}">{{ value }}</option>
 | 
					 | 
				
			||||||
                        {% endfor %}
 | 
					 | 
				
			||||||
                        </select>
 | 
					 | 
				
			||||||
                    {% else %}
 | 
					 | 
				
			||||||
                      <input type="hidden" name="configuration_detail" value="{{configuration_detail}}">
 | 
					 | 
				
			||||||
                      <input type="hidden" name="configuration" value="{{hosting}}">
 | 
					 | 
				
			||||||
                      <!-- Single button -->
 | 
					 | 
				
			||||||
                      <div class="btn-group">
 | 
					 | 
				
			||||||
                        <div class="form-group">
 | 
					 | 
				
			||||||
                          <label>Configuration: </label>
 | 
					 | 
				
			||||||
                          {{configuration_detail}}
 | 
					 | 
				
			||||||
                        </div>
 | 
					 | 
				
			||||||
                      </div>
 | 
					 | 
				
			||||||
                    {% endif %}
 | 
					 | 
				
			||||||
                  </li>
 | 
					 | 
				
			||||||
                  <li>
 | 
					 | 
				
			||||||
                    <!-- Single button -->
 | 
					 | 
				
			||||||
                    <div class="btn-group">
 | 
					 | 
				
			||||||
                      <div class="form-group">
 | 
					 | 
				
			||||||
                        <label for="cores">Cores: </label> 
 | 
					 | 
				
			||||||
                        <select class="form-control cores-selector" name="cores" id="{{vm.hosting_company}}-cores" data-vm-type="{{vm.hosting_company}}">
 | 
					 | 
				
			||||||
                        {% with ''|center:10 as range %}
 | 
					 | 
				
			||||||
                        {% for _ in range %}
 | 
					 | 
				
			||||||
                            <option>{{ forloop.counter }}</option>
 | 
					 | 
				
			||||||
                        {% endfor %}
 | 
					 | 
				
			||||||
                        {% endwith %}
 | 
					 | 
				
			||||||
                        </select>
 | 
					 | 
				
			||||||
                      </div>
 | 
					                      </div>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,30 +42,28 @@
 | 
				
			||||||
                  <li>
 | 
					                  <li>
 | 
				
			||||||
                    <div class="form-group">
 | 
					                    <div class="form-group">
 | 
				
			||||||
                      <div class="btn-group">
 | 
					                      <div class="btn-group">
 | 
				
			||||||
                        <label for="memory">Memory: </label> 
 | 
					                        <label for="memory">Memory: {{vm.memory}} GiB</label> 
 | 
				
			||||||
                        <select class="form-control memory-selector" name="memory" id="{{vm.hosting_company}}-memory" data-vm-type="{{vm.hosting_company}}">
 | 
					 | 
				
			||||||
                        {% with ''|center:50 as range %}
 | 
					 | 
				
			||||||
                        {% for _ in range %}
 | 
					 | 
				
			||||||
                            <option>{{ forloop.counter }}</option>
 | 
					 | 
				
			||||||
                        {% endfor %}
 | 
					 | 
				
			||||||
                        {% endwith %}
 | 
					 | 
				
			||||||
                        </select>
 | 
					 | 
				
			||||||
                        <span>GiB</span>
 | 
					 | 
				
			||||||
                      </div>
 | 
					                      </div>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                  </li>           
 | 
					                  </li>           
 | 
				
			||||||
                  <li>
 | 
					                  <li>
 | 
				
			||||||
                    <div class="form-group row">
 | 
					                    <div class="form-group row">
 | 
				
			||||||
                      <div class="col-xs-offset-1 col-xs-9 col-sm-12 col-md-12 col-md-offset-0">
 | 
					                      <div class="col-xs-offset-1 col-xs-9 col-sm-12 col-md-12 col-md-offset-0">
 | 
				
			||||||
                        <label for="Disk Size">Disk Size: </label>
 | 
					                        <label for="Disk Size">Disk Size: {{vm.disk_size}} GiB</label>
 | 
				
			||||||
                        <input class="form-control short-input text-center disk-space-selector" name="disk_space" type="number" id="{{vm.hosting_company}}-disk_space" min="10" value="10" step="10" data-vm-type="{{vm.hosting_company}}"/>
 | 
					 | 
				
			||||||
                        <span>GiB</span>
 | 
					 | 
				
			||||||
                      </div>
 | 
					                      </div>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                  </li>
 | 
					                  </li>
 | 
				
			||||||
                  <li>
 | 
					                  <li>
 | 
				
			||||||
                    <input id="{{vm.hosting_company}}-final-price-input" type="hidden" name="final_price" value="{{vm.default_price|floatformat}}">
 | 
					                  <label for="configuration">Configuration: </label>
 | 
				
			||||||
                    <h3 id="{{vm.hosting_company}}-final-price">{{vm.default_price|floatformat}}CHF</h3>
 | 
					                        <select class="form-control" name="configuration" id="{{vm.hosting_company}}-configuration" data-vm-type="{{vm.hosting_company}}">
 | 
				
			||||||
 | 
					                        {% for key,value in configuration_options.items   %}
 | 
				
			||||||
 | 
					                            <option  value="{{key}}">{{ value }}</option>
 | 
				
			||||||
 | 
					                        {% endfor %}
 | 
				
			||||||
 | 
					                        </select>
 | 
				
			||||||
 | 
					                  </li>
 | 
				
			||||||
 | 
					                  <li>
 | 
				
			||||||
 | 
					                    <input type="hidden" name="final_price" value="{{vm.final_price|floatformat}}">
 | 
				
			||||||
 | 
					                    <h3 id="{{vm.hosting_company}}-final-price">{{vm.final_price|floatformat}}CHF</h3>
 | 
				
			||||||
                    <span>per month</span>
 | 
					                    <span>per month</span>
 | 
				
			||||||
                  </li>
 | 
					                  </li>
 | 
				
			||||||
                  <li>
 | 
					                  <li>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,7 @@
 | 
				
			||||||
            {% url 'hosting:payment' as payment_url %}
 | 
					            {% url 'hosting:payment' as payment_url %}
 | 
				
			||||||
            {% if payment_url in request.META.HTTP_REFERER  %}
 | 
					            {% if payment_url in request.META.HTTP_REFERER  %}
 | 
				
			||||||
            <div class=" content pull-right">
 | 
					            <div class=" content pull-right">
 | 
				
			||||||
                <a href="{% url 'hosting:virtual_machine_key' order.vm_plan.id %}" ><button class="btn btn-info">{% trans "Finish Configuration"%}</button></a>
 | 
					                <a href="{% url 'hosting:key_pair'%}" ><button class="btn btn-info">{% trans "Finish Configuration"%}</button></a>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            {% endif %}
 | 
					            {% endif %}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,11 +86,11 @@
 | 
				
			||||||
							<h3><b>Billing Amount</b></h3>
 | 
												<h3><b>Billing Amount</b></h3>
 | 
				
			||||||
							<hr>
 | 
												<hr>
 | 
				
			||||||
							<div class="content">
 | 
												<div class="content">
 | 
				
			||||||
								<p><b>Type</b> <span class="pull-right">{{request.session.vm_specs.location_code}}</span></p>
 | 
													<!-- <p><b>Type</b> <span class="pull-right">{{request.session.vm_specs.location_code}}</span></p> -->
 | 
				
			||||||
								<hr>
 | 
													<!-- <hr> -->
 | 
				
			||||||
								<p><b>Cores</b> <span class="pull-right">{{request.session.vm_specs.cores}}</span></p>
 | 
													<p><b>Cores</b> <span class="pull-right">{{request.session.vm_specs.cores}}</span></p>
 | 
				
			||||||
								<hr>
 | 
													<hr>
 | 
				
			||||||
								<p><b>Configuration</b> <span class="pull-right">{{request.session.vm_specs.configuration_detail}}</span></p>
 | 
													<p><b>Configuration</b> <span class="pull-right">{{request.session.vm_specs.configuration_display}}</span></p>
 | 
				
			||||||
								<hr>								
 | 
													<hr>								
 | 
				
			||||||
								<p><b>Memory</b> <span class="pull-right">{{request.session.vm_specs.memory}} GiB</span></p>
 | 
													<p><b>Memory</b> <span class="pull-right">{{request.session.vm_specs.memory}} GiB</span></p>
 | 
				
			||||||
								<hr>
 | 
													<hr>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,30 +6,75 @@
 | 
				
			||||||
		<div class="row">
 | 
							<div class="row">
 | 
				
			||||||
			<div class="col-md-9 col-md-offset-2">
 | 
								<div class="col-md-9 col-md-offset-2">
 | 
				
			||||||
				 <div  class="col-sm-12">
 | 
									 <div  class="col-sm-12">
 | 
				
			||||||
 | 
					                    <form method="POST" action="" >
 | 
				
			||||||
				        <h3><i class="fa fa-key" aria-hidden="true"></i>{% trans "SSH Private Key"%} </h3>
 | 
					                        {% csrf_token %}
 | 
				
			||||||
 | 
									        <h3><i class="fa fa-key" aria-hidden="true"></i>{% trans "Access Key"%} </h3>
 | 
				
			||||||
				        <hr/>	
 | 
									        <hr/>	
 | 
				
			||||||
 | 
					                        {% if not user_key %}
 | 
				
			||||||
 | 
					                            <div class="alert alert-warning">
 | 
				
			||||||
 | 
					                                {% trans "Upload your own key. "%} 
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                            <div class="form-group">
 | 
				
			||||||
 | 
					                              <label for="comment">Paste here your public key</label>
 | 
				
			||||||
 | 
					                              <textarea class="form-control" rows="6" name="public_key"></textarea>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                            <div class="form-group">
 | 
				
			||||||
 | 
					                                <button class="btn btn-success">{% trans "Upload Key"%} </a>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
 | 
					                            <div class="alert alert-warning">
 | 
				
			||||||
 | 
					                                {% trans "Or generate a new key pair."%} 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                            <div class="form-group">
 | 
				
			||||||
 | 
					                                <button class="btn btn-success">{% trans "Generate Key Pair"%} </a>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                        {% else %}
 | 
				
			||||||
 | 
					                            <h5> Use your created key to access to the machine. If you lost it, contact us. </h5>
 | 
				
			||||||
 | 
					                            <table class="table borderless table-hover"> 
 | 
				
			||||||
 | 
					                                <br/>
 | 
				
			||||||
 | 
					                                <thead> 
 | 
				
			||||||
 | 
					                                <tr> 
 | 
				
			||||||
 | 
					                                    <th>{% trans "Name"%}</th>
 | 
				
			||||||
 | 
					                                    <th>{% trans "Created at"%} </th>
 | 
				
			||||||
 | 
					                                    <th>{% trans "Status"%} </th>
 | 
				
			||||||
 | 
					                                    <th></th>
 | 
				
			||||||
 | 
					                                </tr>
 | 
				
			||||||
 | 
					                                </thead>
 | 
				
			||||||
 | 
					                                <tbody> 
 | 
				
			||||||
 | 
					                                    <tr> 
 | 
				
			||||||
 | 
					                                        <td scope="row">{{user_key.name}}</td> 
 | 
				
			||||||
 | 
					                                        <td>{{user_key.created_at}}</td> 
 | 
				
			||||||
 | 
					                                        <td>
 | 
				
			||||||
 | 
					                                            <span class="h3 label label-success"><strong>Active</strong></span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                        </td> 
 | 
				
			||||||
 | 
					                                    </tr>
 | 
				
			||||||
 | 
					                                </tbody> 
 | 
				
			||||||
 | 
					                            </table>
 | 
				
			||||||
 | 
					                        {% endif %}
 | 
				
			||||||
 | 
					                    </form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				        {% if private_key %}
 | 
									        {% if private_key %}
 | 
				
			||||||
				 		<div class="alert alert-warning">
 | 
									 		<div class="alert alert-warning">
 | 
				
			||||||
				 			 
 | 
									 			 
 | 
				
			||||||
  							<strong>{% trans "Warning!"%}</strong>{% trans "You can view your SSH  private key once. Copy it or if it wasn't downloaded automatically, just click on Download to start it."%}  
 | 
					  							<strong>{% trans "Warning!"%}</strong>{% trans "You can view your SSH  private key once. Copy it or if it wasn't downloaded automatically, just click on Download to start it."%}  
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
						<div class="form-group">
 | 
											<div class="form-group">
 | 
				
			||||||
						  <label for="comment">private_key.pem</label>
 | 
											  <textarea class="form-control" rows="6" id="ssh_key" type="hidden" style="display:none">{{private_key}}</textarea>
 | 
				
			||||||
						  <textarea class="form-control" rows="6" id="ssh_key">{{private_key}}</textarea>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
							<div  class="form-group pull-right">
 | 
					<!-- 							<div  class="form-group pull-right">
 | 
				
			||||||
								<button type="button" id="copy_to_clipboard" data-clipboard-target="#ssh_key" class="btn btn-warning"
 | 
													<button type="button" id="copy_to_clipboard" data-clipboard-target="#ssh_key" class="btn btn-warning"
 | 
				
			||||||
									data-toggle="tooltip"  data-placement="bottom" title="Copied"  data-trigger="click">{% trans "Copy to Clipboard"%}</button>
 | 
														data-toggle="tooltip"  data-placement="bottom" title="Copied"  data-trigger="click">{% trans "Copy to Clipboard"%}</button>
 | 
				
			||||||
								<button type="button" id="download_ssh_key" class="btn btn-warning">{% trans "Download"%}</button>  
 | 
													<button type="button" id="download_ssh_key" class="btn btn-warning">{% trans "Download"%}</button>  
 | 
				
			||||||
							</div>				        
 | 
												</div> -->				        
 | 
				
			||||||
						{% else %}
 | 
											{% else %}
 | 
				
			||||||
					 		<div class="alert alert-warning">
 | 
					<!-- 					 		<div class="alert alert-warning">
 | 
				
			||||||
	  							<strong>{% trans "Warning!"%}</strong>{% trans "Your SSH private key was already generated and downloaded, if you lost it, contact us. "%} 
 | 
						  							<strong>{% trans "Warning!"%}</strong>{% trans "Your SSH private key was already generated and downloaded, if you lost it, contact us. "%} 
 | 
				
			||||||
							</div>
 | 
												</div>
 | 
				
			||||||
						{% endif %}
 | 
					 -->						{% endif %}
 | 
				
			||||||
						<a class="btn btn-success" href="{% url 'hosting:virtual_machines' virtual_machine.id %}">{% trans "Go to my Virtual Machine Dashboard"%} </a>
 | 
											<!-- <a class="btn btn-success" href="{% url 'hosting:virtual_machines' %}">{% trans "Generate my key"%} </a> -->
 | 
				
			||||||
						<div class="clearfix"></div>
 | 
											<div class="clearfix"></div>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
| 
						 | 
					@ -43,10 +88,11 @@
 | 
				
			||||||
<script type="text/javascript"> 
 | 
					<script type="text/javascript"> 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        var key = window.document.getElementById('ssh_key');
 | 
					        var key = window.document.getElementById('ssh_key');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var a = window.document.createElement('a');
 | 
							var a = window.document.createElement('a');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		a.href = window.URL.createObjectURL(new Blob(['key'], {type: 'text'}));
 | 
							a.href = window.URL.createObjectURL(new Blob([key.value], {type: 'text'}));
 | 
				
			||||||
		a.download = 'private_key.pem';
 | 
							a.download = '{{key_name}}.pem';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Append anchor to body.
 | 
							// Append anchor to body.
 | 
				
			||||||
		document.body.appendChild(a);
 | 
							document.body.appendChild(a);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,10 @@
 | 
				
			||||||
		<div class="row">
 | 
							<div class="row">
 | 
				
			||||||
			<div class="col-md-8 col-md-offset-2">
 | 
								<div class="col-md-8 col-md-offset-2">
 | 
				
			||||||
				<table class="table borderless table-hover"> 
 | 
									<table class="table borderless table-hover"> 
 | 
				
			||||||
				<h3><i class="fa fa-server" aria-hidden="true"></i>{% trans "Virtual Machines"%} </h3> 
 | 
									<h3 class="pull-left"><i class="fa fa-server" aria-hidden="true"></i> {% trans "Virtual Machines"%} </h3>
 | 
				
			||||||
 | 
					                <p class="pull-right">
 | 
				
			||||||
 | 
					                    <a class="btn btn-success" href="{% url 'hosting:create-virtual-machine' %}" >{% trans "Create VM"%} </a>                    
 | 
				
			||||||
 | 
					                </p>
 | 
				
			||||||
				<br/>
 | 
									<br/>
 | 
				
			||||||
				<thead> 
 | 
									<thead> 
 | 
				
			||||||
				<tr> 
 | 
									<tr> 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,8 @@ from .views import DjangoHostingView, RailsHostingView, PaymentVMView,\
 | 
				
			||||||
    NodeJSHostingView, LoginView, SignupView, IndexView, \
 | 
					    NodeJSHostingView, LoginView, SignupView, IndexView, \
 | 
				
			||||||
    OrdersHostingListView, OrdersHostingDetailView, VirtualMachinesPlanListView,\
 | 
					    OrdersHostingListView, OrdersHostingDetailView, VirtualMachinesPlanListView,\
 | 
				
			||||||
    VirtualMachineView, GenerateVMSSHKeysView, OrdersHostingDeleteView, NotificationsView, \
 | 
					    VirtualMachineView, GenerateVMSSHKeysView, OrdersHostingDeleteView, NotificationsView, \
 | 
				
			||||||
    MarkAsReadNotificationView, PasswordResetView, PasswordResetConfirmView, HostingPricingView
 | 
					    MarkAsReadNotificationView, PasswordResetView, PasswordResetConfirmView, HostingPricingView,\
 | 
				
			||||||
 | 
					    CreateVirtualMachinesView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
urlpatterns = [
 | 
					urlpatterns = [
 | 
				
			||||||
    url(r'index/?$', IndexView.as_view(), name='index'),
 | 
					    url(r'index/?$', IndexView.as_view(), name='index'),
 | 
				
			||||||
| 
						 | 
					@ -16,13 +17,14 @@ urlpatterns = [
 | 
				
			||||||
    url(r'orders/?$', OrdersHostingListView.as_view(), name='orders'),
 | 
					    url(r'orders/?$', OrdersHostingListView.as_view(), name='orders'),
 | 
				
			||||||
    url(r'orders/(?P<pk>\d+)/?$', OrdersHostingDetailView.as_view(), name='orders'),
 | 
					    url(r'orders/(?P<pk>\d+)/?$', OrdersHostingDetailView.as_view(), name='orders'),
 | 
				
			||||||
    url(r'cancel_order/(?P<pk>\d+)/?$', OrdersHostingDeleteView.as_view(), name='delete_order'),
 | 
					    url(r'cancel_order/(?P<pk>\d+)/?$', OrdersHostingDeleteView.as_view(), name='delete_order'),
 | 
				
			||||||
 | 
					    url(r'create-virtual-machine/?$', CreateVirtualMachinesView.as_view(), name='create-virtual-machine'),
 | 
				
			||||||
    url(r'my-virtual-machines/?$', VirtualMachinesPlanListView.as_view(), name='virtual_machines'),
 | 
					    url(r'my-virtual-machines/?$', VirtualMachinesPlanListView.as_view(), name='virtual_machines'),
 | 
				
			||||||
    url(r'my-virtual-machines/(?P<pk>\d+)/?$', VirtualMachineView.as_view(),
 | 
					    url(r'my-virtual-machines/(?P<pk>\d+)/?$', VirtualMachineView.as_view(),
 | 
				
			||||||
        name='virtual_machines'),
 | 
					        name='virtual_machines'),
 | 
				
			||||||
    # url(r'my-virtual-machines/(?P<pk>\d+)/delete/?$', VirtualMachineCancelView.as_view(),
 | 
					    # url(r'my-virtual-machines/(?P<pk>\d+)/delete/?$', VirtualMachineCancelView.as_view(),
 | 
				
			||||||
        # name='virtual_machines_cancel'),
 | 
					        # name='virtual_machines_cancel'),
 | 
				
			||||||
    url(r'my-virtual-machines/(?P<pk>\d+)/key/?$', GenerateVMSSHKeysView.as_view(),
 | 
					    url(r'vm-key-pair/?$', GenerateVMSSHKeysView.as_view(),
 | 
				
			||||||
        name='virtual_machine_key'),
 | 
					        name='key_pair'),
 | 
				
			||||||
    url(r'^notifications/$', NotificationsView.as_view(), name='notifications'),
 | 
					    url(r'^notifications/$', NotificationsView.as_view(), name='notifications'),
 | 
				
			||||||
    url(r'^notifications/(?P<pk>\d+)/?$', MarkAsReadNotificationView.as_view(),
 | 
					    url(r'^notifications/(?P<pk>\d+)/?$', MarkAsReadNotificationView.as_view(),
 | 
				
			||||||
        name='read_notification'),
 | 
					        name='read_notification'),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										102
									
								
								hosting/views.py
									
										
									
									
									
								
							
							
						
						
									
										102
									
								
								hosting/views.py
									
										
									
									
									
								
							| 
						 | 
					@ -8,6 +8,8 @@ from django.views.generic import View, CreateView, FormView, ListView, DetailVie
 | 
				
			||||||
from django.http import HttpResponseRedirect
 | 
					from django.http import HttpResponseRedirect
 | 
				
			||||||
from django.contrib.auth import authenticate, login
 | 
					from django.contrib.auth import authenticate, login
 | 
				
			||||||
from django.conf import settings
 | 
					from django.conf import settings
 | 
				
			||||||
 | 
					from django.shortcuts import redirect
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from guardian.mixins import PermissionRequiredMixin
 | 
					from guardian.mixins import PermissionRequiredMixin
 | 
				
			||||||
from stored_messages.settings import stored_messages_settings
 | 
					from stored_messages.settings import stored_messages_settings
 | 
				
			||||||
| 
						 | 
					@ -15,13 +17,14 @@ from stored_messages.models import Message
 | 
				
			||||||
from stored_messages.api import mark_read
 | 
					from stored_messages.api import mark_read
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from membership.models import CustomUser, StripeCustomer
 | 
					from membership.models import CustomUser, StripeCustomer
 | 
				
			||||||
from utils.stripe_utils import StripeUtils
 | 
					from utils.stripe_utils import StripeUtils
 | 
				
			||||||
from utils.forms import BillingAddressForm, PasswordResetRequestForm
 | 
					from utils.forms import BillingAddressForm, PasswordResetRequestForm
 | 
				
			||||||
from utils.views import PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin
 | 
					from utils.views import PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin
 | 
				
			||||||
from utils.mailer import BaseEmail
 | 
					from utils.mailer import BaseEmail
 | 
				
			||||||
from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder
 | 
					from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder, UserHostingKey
 | 
				
			||||||
from .forms import HostingUserSignupForm, HostingUserLoginForm
 | 
					from .forms import HostingUserSignupForm, HostingUserLoginForm, UserHostingKeyForm
 | 
				
			||||||
from .mixins import ProcessVMSelectionMixin
 | 
					from .mixins import ProcessVMSelectionMixin
 | 
				
			||||||
from .opennebula_functions import HostingManageVMAdmin
 | 
					from .opennebula_functions import HostingManageVMAdmin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,6 +43,7 @@ class DjangoHostingView(ProcessVMSelectionMixin, View):
 | 
				
			||||||
            'google_analytics': "UA-62285904-6",
 | 
					            'google_analytics': "UA-62285904-6",
 | 
				
			||||||
            'email': "info@django-hosting.ch",
 | 
					            'email': "info@django-hosting.ch",
 | 
				
			||||||
            'vm_types': VirtualMachineType.get_serialized_vm_types(),
 | 
					            'vm_types': VirtualMachineType.get_serialized_vm_types(),
 | 
				
			||||||
 | 
					            'configuration_options': dict(VirtualMachinePlan.VM_CONFIGURATION)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return context
 | 
					        return context
 | 
				
			||||||
| 
						 | 
					@ -208,25 +212,51 @@ class MarkAsReadNotificationView(LoginRequiredMixin, UpdateView):
 | 
				
			||||||
        return HttpResponseRedirect(reverse('hosting:notifications'))
 | 
					        return HttpResponseRedirect(reverse('hosting:notifications'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GenerateVMSSHKeysView(LoginRequiredMixin, DetailView):
 | 
					class GenerateVMSSHKeysView(LoginRequiredMixin, FormView):
 | 
				
			||||||
    model = VirtualMachinePlan
 | 
					    form_class = UserHostingKeyForm
 | 
				
			||||||
 | 
					    model = UserHostingKey
 | 
				
			||||||
    template_name = 'hosting/virtual_machine_key.html'
 | 
					    template_name = 'hosting/virtual_machine_key.html'
 | 
				
			||||||
    success_url = reverse_lazy('hosting:orders')
 | 
					    success_url = reverse_lazy('hosting:orders')
 | 
				
			||||||
    login_url = reverse_lazy('hosting:login')
 | 
					    login_url = reverse_lazy('hosting:login')
 | 
				
			||||||
    context_object_name = "virtual_machine"
 | 
					    context_object_name = "virtual_machine"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_context_data(self, **kwargs):
 | 
					    def get_context_data(self, **kwargs):
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            user_key = UserHostingKey.objects.get(
 | 
				
			||||||
 | 
					                user=self.request.user
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        except UserHostingKey.DoesNotExist:
 | 
				
			||||||
 | 
					            user_key = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context = super(
 | 
				
			||||||
 | 
					            GenerateVMSSHKeysView,
 | 
				
			||||||
 | 
					            self
 | 
				
			||||||
 | 
					        ).get_context_data(**kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        context = super(GenerateVMSSHKeysView, self).get_context_data(**kwargs)
 | 
					 | 
				
			||||||
        vm = self.get_object()
 | 
					 | 
				
			||||||
        if not vm.public_key:
 | 
					 | 
				
			||||||
            private_key, public_key = vm.generate_keys()
 | 
					 | 
				
			||||||
        context.update({
 | 
					        context.update({
 | 
				
			||||||
                'private_key': private_key,
 | 
					            'user_key': user_key
 | 
				
			||||||
                'public_key': public_key
 | 
					 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return context
 | 
					        return context
 | 
				
			||||||
        return context
 | 
					
 | 
				
			||||||
 | 
					    def get_form_kwargs(self):
 | 
				
			||||||
 | 
					        kwargs = super(GenerateVMSSHKeysView, self).get_form_kwargs()
 | 
				
			||||||
 | 
					        kwargs.update({'request': self.request})
 | 
				
			||||||
 | 
					        return kwargs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def form_valid(self, form):
 | 
				
			||||||
 | 
					        form.save()
 | 
				
			||||||
 | 
					        context = self.get_context_data()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if form.cleaned_data.get('private_key'):
 | 
				
			||||||
 | 
					            context.update({
 | 
				
			||||||
 | 
					                'private_key': form.cleaned_data.get('private_key'),
 | 
				
			||||||
 | 
					                'key_name': form.cleaned_data.get('name')
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # print("form", form.cleaned_data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return render(self.request, self.template_name, context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PaymentVMView(LoginRequiredMixin, FormView):
 | 
					class PaymentVMView(LoginRequiredMixin, FormView):
 | 
				
			||||||
| 
						 | 
					@ -251,11 +281,11 @@ class PaymentVMView(LoginRequiredMixin, FormView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            vm_template = specifications.get('vm_template', 1)
 | 
					            vm_template = specifications.get('vm_template', 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            vm_type = VirtualMachineType.objects.first()
 | 
					            vm_type = VirtualMachineType.objects.get(id=vm_template)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            final_price = VirtualMachineType.get_price(vm_template)
 | 
					            specs = vm_type.get_specs()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            specs = VirtualMachineType.get_specs(vm_template)
 | 
					            final_price = vm_type.calculate_price()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            plan_data = {
 | 
					            plan_data = {
 | 
				
			||||||
                'vm_type': vm_type,
 | 
					                'vm_type': vm_type,
 | 
				
			||||||
| 
						 | 
					@ -318,9 +348,9 @@ class PaymentVMView(LoginRequiredMixin, FormView):
 | 
				
			||||||
                # 'vm_template': vm_template
 | 
					                # 'vm_template': vm_template
 | 
				
			||||||
            # }
 | 
					            # }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin)
 | 
					            # hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin)
 | 
				
			||||||
            hosting_admin.init_opennebula_client(request)
 | 
					            # hosting_admin.init_opennebula_client(request)
 | 
				
			||||||
            hosting_admin.create(request)
 | 
					            # hosting_admin.create(request)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Send notification to ungleich as soon as VM has been booked
 | 
					            # Send notification to ungleich as soon as VM has been booked
 | 
				
			||||||
            context = {
 | 
					            context = {
 | 
				
			||||||
| 
						 | 
					@ -381,13 +411,47 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView):
 | 
				
			||||||
    ordering = '-id'
 | 
					    ordering = '-id'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_queryset(self):
 | 
					    def get_queryset(self):
 | 
				
			||||||
        hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin)
 | 
					        # hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin)
 | 
				
			||||||
        print(hosting_admin.show_vms(self.request))
 | 
					        # print(hosting_admin.show_vms(self.request))
 | 
				
			||||||
        user = self.request.user
 | 
					        user = self.request.user
 | 
				
			||||||
        self.queryset = VirtualMachinePlan.objects.active(user)
 | 
					        self.queryset = VirtualMachinePlan.objects.active(user)
 | 
				
			||||||
        return super(VirtualMachinesPlanListView, self).get_queryset()
 | 
					        return super(VirtualMachinesPlanListView, self).get_queryset()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CreateVirtualMachinesView(LoginRequiredMixin, View):
 | 
				
			||||||
 | 
					    template_name = "hosting/create_virtual_machine.html"
 | 
				
			||||||
 | 
					    login_url = reverse_lazy('hosting:login')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        context = {
 | 
				
			||||||
 | 
					            'vm_types': VirtualMachineType.get_serialized_vm_types(),
 | 
				
			||||||
 | 
					            'configuration_options': VirtualMachinePlan.VM_CONFIGURATION
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        # context = {}
 | 
				
			||||||
 | 
					        return render(request, self.template_name, context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def post(self, request):
 | 
				
			||||||
 | 
					        configuration = request.POST.get('configuration')
 | 
				
			||||||
 | 
					        configuration_display = dict(VirtualMachinePlan.VM_CONFIGURATION).get(configuration)
 | 
				
			||||||
 | 
					        vm_template = request.POST.get('vm_template')
 | 
				
			||||||
 | 
					        vm_type = VirtualMachineType.objects.get(id=vm_template)
 | 
				
			||||||
 | 
					        vm_specs = vm_type.get_specs()
 | 
				
			||||||
 | 
					        vm_specs.update({
 | 
				
			||||||
 | 
					            'configuration_display': configuration_display,
 | 
				
			||||||
 | 
					            'configuration': configuration,
 | 
				
			||||||
 | 
					            'final_price': vm_type.final_price,
 | 
				
			||||||
 | 
					            'vm_template': vm_template
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        return redirect(reverse('hosting:payment'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # def get_queryset(self):
 | 
				
			||||||
 | 
					    #     # hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin)
 | 
				
			||||||
 | 
					    #     # print(hosting_admin.show_vms(self.request))
 | 
				
			||||||
 | 
					    #     user = self.request.user
 | 
				
			||||||
 | 
					    #     self.queryset = VirtualMachinePlan.objects.active(user)
 | 
				
			||||||
 | 
					    #     return super(VirtualMachinesPlanListView, self).get_queryset()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VirtualMachineView(PermissionRequiredMixin, LoginRequiredMixin, UpdateView):
 | 
					class VirtualMachineView(PermissionRequiredMixin, LoginRequiredMixin, UpdateView):
 | 
				
			||||||
    template_name = "hosting/virtual_machine_detail.html"
 | 
					    template_name = "hosting/virtual_machine_detail.html"
 | 
				
			||||||
    login_url = reverse_lazy('hosting:login')
 | 
					    login_url = reverse_lazy('hosting:login')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue