mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-11-07 13:56:01 +01:00
Docker app beta
This commit is contained in:
@@ -24,7 +24,7 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|||||||
SECRET_KEY = 'xr%j*p!*$0d%(-(e%@-*hyoz4$f%y77coq0u)6pwmjg4)q&19f'
|
SECRET_KEY = 'xr%j*p!*$0d%(-(e%@-*hyoz4$f%y77coq0u)6pwmjg4)q&19f'
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = False
|
DEBUG = True
|
||||||
|
|
||||||
ALLOWED_HOSTS = ['*']
|
ALLOWED_HOSTS = ['*']
|
||||||
|
|
||||||
@@ -62,9 +62,7 @@ INSTALLED_APPS = [
|
|||||||
'pluginHolder',
|
'pluginHolder',
|
||||||
'emailPremium',
|
'emailPremium',
|
||||||
'emailMarketing',
|
'emailMarketing',
|
||||||
'cloudAPI',
|
'dockerManager'
|
||||||
'highAvailability',
|
|
||||||
's3Backups'
|
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@@ -109,15 +107,15 @@ DATABASES = {
|
|||||||
'ENGINE': 'django.db.backends.mysql',
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
'NAME': 'cyberpanel',
|
'NAME': 'cyberpanel',
|
||||||
'USER': 'cyberpanel',
|
'USER': 'cyberpanel',
|
||||||
'PASSWORD': 'Bz9gF7Hr7X4RtD',
|
'PASSWORD': 'a9AwLb7zY7ZwCd',
|
||||||
'HOST': '127.0.0.1',
|
'HOST': 'localhost',
|
||||||
'PORT':'3307'
|
'PORT': '',
|
||||||
},
|
},
|
||||||
'rootdb': {
|
'rootdb': {
|
||||||
'ENGINE': 'django.db.backends.mysql',
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
'NAME': 'mysql',
|
'NAME': 'mysql',
|
||||||
'USER': 'root',
|
'USER': 'root',
|
||||||
'PASSWORD': 'sXm5VlRaAsXkDd',
|
'PASSWORD': '3bL8X7wGo0kT3b',
|
||||||
'HOST': 'localhost',
|
'HOST': 'localhost',
|
||||||
'PORT': '',
|
'PORT': '',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ urlpatterns = [
|
|||||||
url(r'^', include('loginSystem.urls')),
|
url(r'^', include('loginSystem.urls')),
|
||||||
url(r'^packages/',include('packages.urls')),
|
url(r'^packages/',include('packages.urls')),
|
||||||
url(r'^websites/',include('websiteFunctions.urls')),
|
url(r'^websites/',include('websiteFunctions.urls')),
|
||||||
|
url(r'^docker/',include('dockerManager.urls')),
|
||||||
url(r'^tuning/',include('tuning.urls')),
|
url(r'^tuning/',include('tuning.urls')),
|
||||||
url(r'^ftp/',include('ftp.urls')),
|
url(r'^ftp/',include('ftp.urls')),
|
||||||
url(r'^serverstatus/',include('serverStatus.urls')),
|
url(r'^serverstatus/',include('serverStatus.urls')),
|
||||||
|
|||||||
70
backup/migrations/0001_initial.py
Normal file
70
backup/migrations/0001_initial.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2019-01-07 12:43
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='DBUsers',
|
||||||
|
fields=[
|
||||||
|
('host', models.CharField(db_column='Host', max_length=60, primary_key=True, serialize=False)),
|
||||||
|
('user', models.CharField(db_column='User', max_length=16)),
|
||||||
|
('password', models.CharField(db_column='Password', max_length=41)),
|
||||||
|
('select_priv', models.CharField(db_column='Select_priv', max_length=1)),
|
||||||
|
('insert_priv', models.CharField(db_column='Insert_priv', max_length=1)),
|
||||||
|
('update_priv', models.CharField(db_column='Update_priv', max_length=1)),
|
||||||
|
('delete_priv', models.CharField(db_column='Delete_priv', max_length=1)),
|
||||||
|
('create_priv', models.CharField(db_column='Create_priv', max_length=1)),
|
||||||
|
('drop_priv', models.CharField(db_column='Drop_priv', max_length=1)),
|
||||||
|
('reload_priv', models.CharField(db_column='Reload_priv', max_length=1)),
|
||||||
|
('shutdown_priv', models.CharField(db_column='Shutdown_priv', max_length=1)),
|
||||||
|
('process_priv', models.CharField(db_column='Process_priv', max_length=1)),
|
||||||
|
('file_priv', models.CharField(db_column='File_priv', max_length=1)),
|
||||||
|
('grant_priv', models.CharField(db_column='Grant_priv', max_length=1)),
|
||||||
|
('references_priv', models.CharField(db_column='References_priv', max_length=1)),
|
||||||
|
('index_priv', models.CharField(db_column='Index_priv', max_length=1)),
|
||||||
|
('alter_priv', models.CharField(db_column='Alter_priv', max_length=1)),
|
||||||
|
('show_db_priv', models.CharField(db_column='Show_db_priv', max_length=1)),
|
||||||
|
('super_priv', models.CharField(db_column='Super_priv', max_length=1)),
|
||||||
|
('create_tmp_table_priv', models.CharField(db_column='Create_tmp_table_priv', max_length=1)),
|
||||||
|
('lock_tables_priv', models.CharField(db_column='Lock_tables_priv', max_length=1)),
|
||||||
|
('execute_priv', models.CharField(db_column='Execute_priv', max_length=1)),
|
||||||
|
('repl_slave_priv', models.CharField(db_column='Repl_slave_priv', max_length=1)),
|
||||||
|
('repl_client_priv', models.CharField(db_column='Repl_client_priv', max_length=1)),
|
||||||
|
('create_view_priv', models.CharField(db_column='Create_view_priv', max_length=1)),
|
||||||
|
('show_view_priv', models.CharField(db_column='Show_view_priv', max_length=1)),
|
||||||
|
('create_routine_priv', models.CharField(db_column='Create_routine_priv', max_length=1)),
|
||||||
|
('alter_routine_priv', models.CharField(db_column='Alter_routine_priv', max_length=1)),
|
||||||
|
('create_user_priv', models.CharField(db_column='Create_user_priv', max_length=1)),
|
||||||
|
('event_priv', models.CharField(db_column='Event_priv', max_length=1)),
|
||||||
|
('trigger_priv', models.CharField(db_column='Trigger_priv', max_length=1)),
|
||||||
|
('create_tablespace_priv', models.CharField(db_column='Create_tablespace_priv', max_length=1)),
|
||||||
|
('ssl_type', models.CharField(max_length=9)),
|
||||||
|
('ssl_cipher', models.TextField()),
|
||||||
|
('x509_issuer', models.TextField()),
|
||||||
|
('x509_subject', models.TextField()),
|
||||||
|
('max_questions', models.IntegerField()),
|
||||||
|
('max_updates', models.IntegerField()),
|
||||||
|
('max_connections', models.IntegerField()),
|
||||||
|
('max_user_connections', models.IntegerField()),
|
||||||
|
('plugin', models.CharField(max_length=64)),
|
||||||
|
('authentication_string', models.TextField()),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'user',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='dbusers',
|
||||||
|
unique_together=set([('host', 'user')]),
|
||||||
|
),
|
||||||
|
]
|
||||||
24
baseTemplate/migrations/0001_initial.py
Normal file
24
baseTemplate/migrations/0001_initial.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2019-01-07 12:43
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='version',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('currentVersion', models.CharField(max_length=50)),
|
||||||
|
('build', models.IntegerField()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -666,6 +666,7 @@
|
|||||||
<script src="{% static 'managePHP/managePHP.js' %}"></script>
|
<script src="{% static 'managePHP/managePHP.js' %}"></script>
|
||||||
<script src="{% static 'baseTemplate/bootstrap-toggle.min.js' %}"></script>
|
<script src="{% static 'baseTemplate/bootstrap-toggle.min.js' %}"></script>
|
||||||
<script src="{% static 'firewall/firewall.js' %}"></script>
|
<script src="{% static 'firewall/firewall.js' %}"></script>
|
||||||
|
<script src="{% static 'dockerManager/dockerManager.js' %}"></script>
|
||||||
<script src="{% static 'manageSSL/manageSSL.js' %}"></script>
|
<script src="{% static 'manageSSL/manageSSL.js' %}"></script>
|
||||||
<script src="{% static 'manageServices/manageServices.js' %}"></script>
|
<script src="{% static 'manageServices/manageServices.js' %}"></script>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
27
databases/migrations/0001_initial.py
Normal file
27
databases/migrations/0001_initial.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2019-01-07 12:43
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('websiteFunctions', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Databases',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('dbName', models.CharField(max_length=50, unique=True)),
|
||||||
|
('dbUser', models.CharField(max_length=50, unique=True)),
|
||||||
|
('website', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='websiteFunctions.Websites')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
125
dns/migrations/0001_initial.py
Normal file
125
dns/migrations/0001_initial.py
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2019-01-07 12:43
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('loginSystem', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Comments',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('domain_id', models.IntegerField()),
|
||||||
|
('name', models.CharField(max_length=255)),
|
||||||
|
('type', models.CharField(max_length=10)),
|
||||||
|
('modified_at', models.IntegerField()),
|
||||||
|
('account', models.CharField(max_length=40)),
|
||||||
|
('comment', models.CharField(max_length=64000)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'comments',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Cryptokeys',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('domain_id', models.IntegerField()),
|
||||||
|
('flags', models.IntegerField()),
|
||||||
|
('active', models.IntegerField(blank=True, null=True)),
|
||||||
|
('content', models.TextField(blank=True, null=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'cryptokeys',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Domainmetadata',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('domain_id', models.IntegerField()),
|
||||||
|
('kind', models.CharField(blank=True, max_length=32, null=True)),
|
||||||
|
('content', models.TextField(blank=True, null=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'domainmetadata',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Domains',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=255, unique=True)),
|
||||||
|
('master', models.CharField(blank=True, max_length=128, null=True)),
|
||||||
|
('last_check', models.IntegerField(blank=True, null=True)),
|
||||||
|
('type', models.CharField(max_length=6)),
|
||||||
|
('notified_serial', models.IntegerField(blank=True, null=True)),
|
||||||
|
('account', models.CharField(blank=True, max_length=40, null=True)),
|
||||||
|
('admin', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='loginSystem.Administrator')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'domains',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Records',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(primary_key=True, serialize=False)),
|
||||||
|
('domain_id', models.IntegerField(blank=True, null=True)),
|
||||||
|
('name', models.CharField(blank=True, max_length=255, null=True)),
|
||||||
|
('type', models.CharField(blank=True, max_length=10, null=True)),
|
||||||
|
('content', models.CharField(blank=True, max_length=64000, null=True)),
|
||||||
|
('ttl', models.IntegerField(blank=True, null=True)),
|
||||||
|
('prio', models.IntegerField(blank=True, null=True)),
|
||||||
|
('change_date', models.IntegerField(blank=True, null=True)),
|
||||||
|
('disabled', models.IntegerField(blank=True, null=True)),
|
||||||
|
('ordername', models.CharField(blank=True, max_length=255, null=True)),
|
||||||
|
('auth', models.IntegerField(blank=True, null=True)),
|
||||||
|
('domainOwner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='dns.Domains')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'records',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Supermasters',
|
||||||
|
fields=[
|
||||||
|
('ip', models.CharField(max_length=64, primary_key=True, serialize=False)),
|
||||||
|
('nameserver', models.CharField(max_length=255)),
|
||||||
|
('account', models.CharField(max_length=40)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'supermasters',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Tsigkeys',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(blank=True, max_length=255, null=True)),
|
||||||
|
('algorithm', models.CharField(blank=True, max_length=50, null=True)),
|
||||||
|
('secret', models.CharField(blank=True, max_length=255, null=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'tsigkeys',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='tsigkeys',
|
||||||
|
unique_together=set([('name', 'algorithm')]),
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='supermasters',
|
||||||
|
unique_together=set([('ip', 'nameserver')]),
|
||||||
|
),
|
||||||
|
]
|
||||||
0
dockerManager/__init__.py
Normal file
0
dockerManager/__init__.py
Normal file
6
dockerManager/admin.py
Normal file
6
dockerManager/admin.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
||||||
8
dockerManager/apps.py
Normal file
8
dockerManager/apps.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class DockermanagerConfig(AppConfig):
|
||||||
|
name = 'dockerManager'
|
||||||
47
dockerManager/decorators.py
Normal file
47
dockerManager/decorators.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
from django.shortcuts import render,redirect
|
||||||
|
from loginSystem.models import Administrator
|
||||||
|
import os
|
||||||
|
import docker
|
||||||
|
import json
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from loginSystem.views import loadLoginPage
|
||||||
|
|
||||||
|
def preDockerRun(function):
|
||||||
|
def wrap(request, *args, **kwargs):
|
||||||
|
|
||||||
|
try:
|
||||||
|
val = request.session['userID']
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
admin = Administrator.objects.get(pk=val)
|
||||||
|
|
||||||
|
if request.method == "POST":
|
||||||
|
isPost = True
|
||||||
|
else:
|
||||||
|
isPost = False
|
||||||
|
|
||||||
|
# check if docker is installed
|
||||||
|
dockerInstallPath = '/usr/bin/docker'
|
||||||
|
if not os.path.exists(dockerInstallPath):
|
||||||
|
if isPost:
|
||||||
|
data_ret = {'status': 0, 'error_message': 'Docker not installed'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
else:
|
||||||
|
return render(request, 'dockerManager/install.html', {'status':admin.type, 'conErr':0})
|
||||||
|
|
||||||
|
# Check if docker is running and we are able to connect
|
||||||
|
try:
|
||||||
|
client = docker.from_env()
|
||||||
|
client.ping()
|
||||||
|
except:
|
||||||
|
if isPost:
|
||||||
|
data_ret = {'status': 0, 'error_message': 'Docker daemon not running or not responsive'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
else:
|
||||||
|
return render(request, 'dockerManager/install.html', {'status':admin.type, 'conErr':1})
|
||||||
|
|
||||||
|
return function(request, *args, **kwargs)
|
||||||
|
return wrap
|
||||||
17
dockerManager/models.py
Normal file
17
dockerManager/models.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
|
from loginSystem.models import Administrator
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
|
class Containers(models.Model):
|
||||||
|
name = models.CharField(max_length=50,unique=True)
|
||||||
|
cid = models.CharField(max_length=64, default='')
|
||||||
|
admin = models.ForeignKey(Administrator)
|
||||||
|
image = models.CharField(max_length=50, default='unknown')
|
||||||
|
tag = models.CharField(max_length=50, default='unknown')
|
||||||
|
memory = models.IntegerField(default=0)
|
||||||
|
ports = models.TextField(default="{}")
|
||||||
|
env = models.TextField(default="{}")
|
||||||
|
startOnReboot = models.IntegerField(default=0)
|
||||||
12
dockerManager/pluginManager.py
Normal file
12
dockerManager/pluginManager.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
from signals import *
|
||||||
|
from plogical.pluginManagerGlobal import pluginManagerGlobal
|
||||||
|
|
||||||
|
class pluginManager:
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def preDockerInstallation(request):
|
||||||
|
return pluginManagerGlobal.globalPlug(request, preDockerInstallation)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def postDockerInstallation(request, response):
|
||||||
|
return pluginManagerGlobal.globalPlug(request, postDockerInstallation, response)
|
||||||
10
dockerManager/signals.py
Normal file
10
dockerManager/signals.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# The world is a prison for the believer.
|
||||||
|
## https://www.youtube.com/watch?v=DWfNYztUM1U
|
||||||
|
|
||||||
|
from django.dispatch import Signal
|
||||||
|
|
||||||
|
## This event is fired before CyberPanel core start installation of Docker
|
||||||
|
preDockerInstallation = Signal(providing_args=["request"])
|
||||||
|
|
||||||
|
## This event is fired after CyberPanel core finished intallation of Docker.
|
||||||
|
postDockerInstallation = Signal(providing_args=["request", "response"])
|
||||||
1106
dockerManager/static/dockerManager/dockerManager.js
Normal file
1106
dockerManager/static/dockerManager/dockerManager.js
Normal file
File diff suppressed because it is too large
Load Diff
64
dockerManager/templates/dockerManager/images.html
Normal file
64
dockerManager/templates/dockerManager/images.html
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
{% extends "baseTemplate/index.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Docker Manage Images - CyberPanel" %}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container" ng-controller="manageImages">
|
||||||
|
|
||||||
|
<div id="page-title">
|
||||||
|
<h2>{% trans "Create new container" %}
|
||||||
|
<a href="{% url 'manageImages' %}" class="btn btn-info pull-right" title="{% trans 'Search new images and manage existing ones' %}">Manage Images</a>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel">
|
||||||
|
<div class="panel-body">
|
||||||
|
<h3 class="title-hero">
|
||||||
|
{% trans "Installed Images" %} <img id="imageLoading" src="/static/images/loading.gif" style="display: none;">
|
||||||
|
{{ test }}
|
||||||
|
</h3><br>
|
||||||
|
|
||||||
|
<div class="example-box-wrapper">
|
||||||
|
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="imageList">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name (Installed)</th>
|
||||||
|
<th>Tags</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
{% for name, image in images.items %}
|
||||||
|
<tr>
|
||||||
|
<td>{{image.name}}</td>
|
||||||
|
<td>
|
||||||
|
<select class="form-control tagList" id="{{forloop.counter}}" ng-model="imageTag['{{ image.name2 }}']">
|
||||||
|
{% for tag in image.tags%}
|
||||||
|
<option>{{tag}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a class="btn btn-primary" ng-href="/docker/runContainer/?image={{image.name}}&tag={$ imageTag['{{ image.name2 }}'] $}">{% trans "Create" %}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
67
dockerManager/templates/dockerManager/index.html
Normal file
67
dockerManager/templates/dockerManager/index.html
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
{% extends "baseTemplate/index.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Docker Container Management - CyberPanel" %}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div id="page-title">
|
||||||
|
<h2>{% trans "Docker Container Management" %}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel">
|
||||||
|
<div class="panel-body">
|
||||||
|
|
||||||
|
|
||||||
|
<h3 class="title-hero">
|
||||||
|
{% trans "Available Functions" %}
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="example-box-wrapper">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<a href="{% url 'listContainers' %}" title="{% trans 'Manage Containers' %}" class="tile-box tile-box-shortcut btn-primary">
|
||||||
|
<div class="tile-header">
|
||||||
|
{% trans "Manage Containers" %}
|
||||||
|
</div>
|
||||||
|
<div class="tile-content-wrapper">
|
||||||
|
<i class="glyph-icon icon-dashboard"></i>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<a href="{% url 'containerImage' %}" title="{% trans 'Create new container' %}" class="tile-box tile-box-shortcut btn-primary">
|
||||||
|
<div class="tile-header">
|
||||||
|
{% trans "New Container" %}
|
||||||
|
</div>
|
||||||
|
<div class="tile-content-wrapper">
|
||||||
|
<i class="glyph-icon icon-dashboard"></i>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<a href="{% url 'manageImages' %}" title="{% trans 'Manage Images' %}" class="tile-box tile-box-shortcut btn-primary">
|
||||||
|
<div class="tile-header">
|
||||||
|
{% trans "Manage Images" %}
|
||||||
|
</div>
|
||||||
|
<div class="tile-content-wrapper">
|
||||||
|
<i class="glyph-icon icon-dashboard"></i>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
50
dockerManager/templates/dockerManager/install.html
Normal file
50
dockerManager/templates/dockerManager/install.html
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{% extends "baseTemplate/index.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Install Docker - CyberPanel" %}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div id="page-title">
|
||||||
|
<h2>{% trans "Install Docker" %}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div ng-controller="installDocker" class="panel">
|
||||||
|
<div class="panel-body">
|
||||||
|
<h3 class="title-hero">
|
||||||
|
{% trans "Install Docker" %} <img ng-hide="installDockerStatus" src="{% static 'images/loading.gif' %}">
|
||||||
|
</h3>
|
||||||
|
<div class="example-box-wrapper">
|
||||||
|
|
||||||
|
{% if conErr == 1%}
|
||||||
|
|
||||||
|
{% if status == 1 %}
|
||||||
|
{% trans "Unable to connect to docker daemon, please try restarting docker from service page" %}
|
||||||
|
{% else %}
|
||||||
|
{% trans "You do not have sufficient permissions to access this page" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<p>{% trans "Docker is currently not installed on this server. To manage containers, you must first install it." %}</p>
|
||||||
|
<br>
|
||||||
|
{% if status == 1 %}
|
||||||
|
<button class="btn btn-primary" ng-click="installDocker()">Install Docker</button>
|
||||||
|
{% else %}
|
||||||
|
{% trans "You do not have permissions to install Docker. Please contact your system administrator" %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
177
dockerManager/templates/dockerManager/listContainers.html
Normal file
177
dockerManager/templates/dockerManager/listContainers.html
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
{% extends "baseTemplate/index.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Containers List - CyberPanel" %}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<div id="page-title">
|
||||||
|
<h2 id="domainNamePage">{% trans "List Containers" %}
|
||||||
|
<a class="pull-right btn btn-primary" href="{% url "containerImage" %}">Create</a>
|
||||||
|
</h2>
|
||||||
|
<p>{% trans "Manage containers on server" %}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel">
|
||||||
|
<div class="panel-body">
|
||||||
|
<h3 class="title-hero">
|
||||||
|
{% trans "Containers" %} <img id="imageLoading" src="/static/images/loading.gif" style="display: none;">
|
||||||
|
</h3>
|
||||||
|
<div ng-controller="listContainers" class="example-box-wrapper">
|
||||||
|
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="datatable-example">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Launch</th>
|
||||||
|
<th>Owner</th>
|
||||||
|
<th>Image</th>
|
||||||
|
<th>Tag</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<tr ng-repeat="web in ContainerList track by $index">
|
||||||
|
<td ng-bind="web.name"></td>
|
||||||
|
<td><a href="/docker/view/{$ web.name $}"><img width="30px" height="30" class="center-block" src="{% static 'baseTemplate/assets/image-resources/webPanel.png' %}"></a></td>
|
||||||
|
<td ng-bind="web.admin"></td>
|
||||||
|
<td ng-bind="web.image"></td>
|
||||||
|
<td ng-bind="web.tag"></td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-primary" ng-click="delContainer(web.name)"><i class="fa fa-trash"></i></button>
|
||||||
|
<button class="btn btn-primary" ng-click="showLog(web.name)"><i class="fa fa-file"></i></button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="listFail" class="alert alert-danger">
|
||||||
|
<p>{% trans "Error message:" %} {$ errorMessage $}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-sm-4 col-sm-offset-8">
|
||||||
|
|
||||||
|
<nav aria-label="Page navigation">
|
||||||
|
<ul class="pagination">
|
||||||
|
|
||||||
|
|
||||||
|
{% for items in pagination %}
|
||||||
|
|
||||||
|
<li ng-click="getFurtherContainersFromDB({{ forloop.counter }})" id="webPages"><a href="">{{ forloop.counter }}</a></li>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if showUnlistedContainer %}
|
||||||
|
<h3 class="title-hero">
|
||||||
|
{% trans "Unlisted Containers" %} <i class="fa fa-question-circle" title="{% trans "Containers listed below were either not created through panel or were not saved to database properly" %}"></i>
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="datatable-example">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
{% for container in unlistedContainers %}
|
||||||
|
<tr>
|
||||||
|
<td>{{container.name}}</td>
|
||||||
|
<td>{{container.status}}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-primary" ng-click="delContainer('{{container.name}}', true)"><i class="fa fa-trash"></i></button>
|
||||||
|
<button class="btn btn-primary" ng-click="showLog('{{container.name}}')"><i class="fa fa-file"></i></button>
|
||||||
|
<button class="btn btn-primary" ng-click="assignContainer('{{container.name}}')"><i class="fa fa-user"></i></button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div id="logs" class="modal fade" role="dialog">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
|
||||||
|
<!-- Modal content-->
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
<h4 class="modal-title">Container logs</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<textarea name="logs" class="form-control" id="" cols="30" rows="10">{$ logs $}</textarea>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-primary" ng-click="showLog('', true)">Refresh</button>
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="assign" class="modal fade" role="dialog">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
|
||||||
|
<!-- Modal content-->
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
<h4 class="modal-title">Assign Container to user</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form action="/" class="form-horizontal">
|
||||||
|
<div ng-hide="installationDetailsForm" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Select Owner" %}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<select ng-model="dockerOwner" class="form-control">
|
||||||
|
{% for user in adminNames %}
|
||||||
|
<option>{{user}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-primary" ng-click="submitAssignContainer()">Submit</button>
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
151
dockerManager/templates/dockerManager/manageImages.html
Normal file
151
dockerManager/templates/dockerManager/manageImages.html
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
{% extends "baseTemplate/index.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Docker Manage Images - CyberPanel" %}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container" ng-controller="manageImages">
|
||||||
|
|
||||||
|
<div id="page-title">
|
||||||
|
<h2 id="domainNamePage">{% trans "Manage Images" %}
|
||||||
|
<a class="pull-right btn btn-primary" href="{% url "containerImage" %}">Create</a>
|
||||||
|
</h2>
|
||||||
|
<p>{% trans "On this page you can manage docker images." %}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="history" class="modal fade" role="dialog">
|
||||||
|
<div class="modal-dialog" style="width:96%">
|
||||||
|
|
||||||
|
<!-- Modal content-->
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
<h4 class="modal-title">Image history</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" class="table table-responsive table-striped table-bordered" id="datatable-example">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>CreatedBy</th>
|
||||||
|
<th>Created</th>
|
||||||
|
<th>Comment</th>
|
||||||
|
<th>Size</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<tr ng-repeat="history in historyList track by $index">
|
||||||
|
<th style="word-break: break-all;" ng-bind="history.Id"></th>
|
||||||
|
<th style="word-break: break-all;" ng-bind="history.CreatedBy"></th>
|
||||||
|
<th ng-bind="history.Created"></th>
|
||||||
|
<th ng-bind="history.Comment"></th>
|
||||||
|
<th ng-bind="history.Size"></th>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel">
|
||||||
|
<div class="panel-body">
|
||||||
|
<h3 class="title-hero">
|
||||||
|
{% trans "Images" %}
|
||||||
|
{% trans "Images" %} <img id="imageLoading" src="/static/images/loading.gif" style="display: none;">
|
||||||
|
<button class="btn btn-warning pull-right" ng-click="rmImage(0)" title="{% trans 'Delete unused images' %}">Prune</button>
|
||||||
|
</h3><br>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2"></div>
|
||||||
|
<label class="col-sm-2 control-label">Search Image</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input type="text" ng-change="searchImages()" ng-model="searchString" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2"></div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div class="example-box-wrapper">
|
||||||
|
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="searchResult">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name (search)</th>
|
||||||
|
<th>Tags</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
|
||||||
|
<tr ng-repeat="image in images track by $index">
|
||||||
|
<td>
|
||||||
|
<span ng-bind="image.name"></span>
|
||||||
|
<span ng-show="image.is_official == true"><i class="fa fa-check-circle" title="{% trans 'Official image' %}"></i></span>
|
||||||
|
<span><i class="fa fa-exclamation-circle" ng-attr-title="{$ image.description $}"></i></span>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<select ng-focus="loadTags($event)" ng-click="selectTag()" ng-model="imageTag[image.name2]" ng-options="tag for tag in tagList[image.name2]" ng-attr-id="{$ image.name2 $}" data-pageloaded='0' class="form-control ng-pristine ng-valid ng-empty ng-touched">
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a ng-click="pullImage(image.name, imageTag[image.name2])" class="btn btn-primary">{% trans "Pull" %}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="imageList">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name (Installed)</th>
|
||||||
|
<th>Tags</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
|
||||||
|
{% for name, image in images.items %}
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>{{image.name}}</td>
|
||||||
|
<td>
|
||||||
|
<select class="form-control tagList" id="{{forloop.counter}}">
|
||||||
|
{% for tag in image.tags%}
|
||||||
|
<option>{{tag}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-primary" title="History" ng-click="getHistory({{forloop.counter}})"><i class="fa fa-history"></i></button>
|
||||||
|
<button class="btn btn-primary" title="Delete" ng-click="rmImage({{forloop.counter}})"><i class="fa fa-trash"></i></button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
170
dockerManager/templates/dockerManager/runContainer.html
Normal file
170
dockerManager/templates/dockerManager/runContainer.html
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
{% extends "baseTemplate/index.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Run new container - CyberPanel" %}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div id="page-title">
|
||||||
|
<h2>{% trans "Run Container" %}</h2>
|
||||||
|
<p>{% trans "Modify parameters for your new container" %}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div ng-controller="runContainer" class="panel">
|
||||||
|
<div class="panel-body">
|
||||||
|
<h3 class="title-hero">
|
||||||
|
{% trans "Container Details" %} <img ng-hide="containerCreationLoading" src="{% static 'images/loading.gif' %}">
|
||||||
|
</h3>
|
||||||
|
<div class="example-box-wrapper">
|
||||||
|
|
||||||
|
|
||||||
|
<form name="dockerInstallForm" action="/" class="form-horizontal bordered-row">
|
||||||
|
|
||||||
|
<div ng-hide="installationDetailsForm" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Name" %}</label>
|
||||||
|
<div class="col-sm-6" ng-init="name='{{name}}' ">
|
||||||
|
<input name="name" type="text" class="form-control" ng-model="name" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="installationDetailsForm" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Image" %}</label>
|
||||||
|
<div class="col-sm-6" ng-init="image='{{image}}' ">
|
||||||
|
<input name="image" type="text" class="form-control" ng-model="image" required disabled="disabled">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="installationDetailsForm" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Tag" %}</label>
|
||||||
|
<div class="col-sm-6" ng-init="tag='{{tag}}' ">
|
||||||
|
<input name="tag" type="text" class="form-control" ng-model="tag" required disabled="disabled">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="installationDetailsForm" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Select Owner" %}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<select ng-model="dockerOwner" class="form-control">
|
||||||
|
{% for items in ownerList %}
|
||||||
|
<option>{{ items }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div ng-hide="installationDetailsForm" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Memory limit" %}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input name="memory" type="number" class="form-control" ng-model="memory" required>
|
||||||
|
</div>
|
||||||
|
<div class="current-pack ng-binding">MB</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% for port, protocol in portConfig.items %}
|
||||||
|
|
||||||
|
<div ng-hide="installationDetailsForm" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Port" %}</label>
|
||||||
|
<div class="col-sm-2" ng-init="iport[{{port}}]={{ port }} ">
|
||||||
|
<input name="iport[{{port}}]" type="text" class="form-control" ng-model="iport[{{port}}]" required disabled="disabled">
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-1" ng-init="portType['{{port}}']='{{ protocol }}'" >
|
||||||
|
<input name="portType['{{port}}']" type="text" class="form-control" ng-model="portType['{{port}}']" required disabled="disabled">
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-1 current-pack text-center">to</div>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<input name="eport['{{port}}']" type="number" class="form-control" ng-model="eport['{{port}}']" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<span ng-init="envList = {}"></span>
|
||||||
|
{% for env, value in envList.items %}
|
||||||
|
|
||||||
|
<span ng-init="envList[{{ forloop.counter0 }}] = {'name':'{{env}}' , 'value':'{{value}}'} "></span>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
<hr>
|
||||||
|
<div ng-repeat="env in envList track by $index">
|
||||||
|
|
||||||
|
<div ng-hide="installationDetailsForm" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">
|
||||||
|
<div ng-show="$first">
|
||||||
|
{% trans "ENV" %}
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<input name="$index" type="text" class="form-control" ng-model="envList[$index].name" required>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<input name="$index" type="text" class="form-control" ng-model="envList[$index].value" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="col-md-offset-3">
|
||||||
|
<button type="button" class="btn btn-info" ng-click="addEnvField()">Add more</button>
|
||||||
|
</div><br>
|
||||||
|
<div ng-hide="installationDetailsForm" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label"></label>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<button type="button" ng-click="createContainer()" class="btn btn-primary btn-lg btn-block">{% trans "Create Container" %}</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div ng-hide="installationProgress" class="form-group">
|
||||||
|
<label class="col-sm-2 control-label"></label>
|
||||||
|
<div class="col-sm-7">
|
||||||
|
|
||||||
|
<div class="alert alert-success text-center">
|
||||||
|
<h2>{$ currentStatus $}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="errorMessageBox" class="alert alert-danger">
|
||||||
|
<p>{% trans "Error message:" %} {$ errorMessage $}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="success" class="alert alert-success">
|
||||||
|
<p>{% trans "Container succesfully created." %}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div ng-hide="couldNotConnect" class="alert alert-danger">
|
||||||
|
<p>{% trans "Could not connect to server. Please refresh this page." %}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="installationProgress" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label"></label>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<button type="button" ng-disabled="goBackDisable" ng-click="goBack()" class="btn btn-primary btn-lg btn-block">{% trans "Go Back" %}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
303
dockerManager/templates/dockerManager/viewContainer.html
Normal file
303
dockerManager/templates/dockerManager/viewContainer.html
Normal file
@@ -0,0 +1,303 @@
|
|||||||
|
{% extends "baseTemplate/index.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Container Home - CyberPanel" %}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container" ng-controller="viewContainer">
|
||||||
|
|
||||||
|
<div id="page-title" ng-init="cName='{{name}}'">
|
||||||
|
<h2 id="domainNamePage">{% trans "Manage Container" %}</h2>
|
||||||
|
<p>{% trans "Currently managing: " %} {{ name }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="example-box-wrapper">
|
||||||
|
|
||||||
|
<div class="content-box">
|
||||||
|
|
||||||
|
<h3 class="content-box-header bg-blue">
|
||||||
|
{% trans "Container Information" %}
|
||||||
|
<img id="infoLoading" src="/static/images/loading.gif" style="display: none;">
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="content-box-wrapper">
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="panel">
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="example-box-wrapper">
|
||||||
|
<h3 class="title-hero">
|
||||||
|
{% trans "Memory Usage" %}
|
||||||
|
</h3>
|
||||||
|
<div class="progressbar" data-value="{{ memoryUsage }}">
|
||||||
|
<div class="progressbar-value bg-primary">
|
||||||
|
<div class="progress-overlay"></div>
|
||||||
|
<div class="progress-label">{{ memoryUsage | floatformat:"2" }}%</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<h3 class="title-hero">
|
||||||
|
{% trans "CPU Usage" %}
|
||||||
|
</h3>
|
||||||
|
<div class="progressbar" data-value="{{ cpuUsage }}">
|
||||||
|
<div class="progressbar-value bg-primary">
|
||||||
|
<div class="progress-overlay"></div>
|
||||||
|
<div class="progress-label">{{ cpuUsage }}%</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="panel">
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="example-box-wrapper">
|
||||||
|
{% trans "Container ID" %}: {{cid}}
|
||||||
|
<br>
|
||||||
|
{% trans "Image" %}: {{image}}
|
||||||
|
<span ng-show="'{{image}}' == 'unknown:unknown'" title="Actions involving container recreation cannot be executed">
|
||||||
|
<i class="fa fa-warning"></i>
|
||||||
|
</span>
|
||||||
|
<br>
|
||||||
|
{% if ports %}
|
||||||
|
{% trans "Ports" %}: <br>
|
||||||
|
{% for iport, eport in ports.items %}
|
||||||
|
{{iport}} {% trans "to" %} {{eport}}<br>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="btn btn-warning" data-toggle="modal" data-target="#settings"><i class="fa fa-gear"></i> Settings</button>
|
||||||
|
<button class="btn btn-warning" ng-click="recreate()"><i class="fa fa-refresh"></i> Recreate</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="example-box-wrapper">
|
||||||
|
|
||||||
|
<div class="content-box">
|
||||||
|
|
||||||
|
<h3 class="content-box-header bg-blue">
|
||||||
|
{% trans "Actions" %}
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="content-box-wrapper">
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="panel">
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="example-box-wrapper">
|
||||||
|
<h3 class="title-hero" ng-init="status='{{status}}'">Main Actions
|
||||||
|
<img id="actionLoading" src="/static/images/loading.gif" style="display: none;width: 20px;">
|
||||||
|
</h3>
|
||||||
|
<b>Status:</b> <span ng-bind="status"></span>
|
||||||
|
<span ng-click='refreshStatus()' style="cursor:pointer;" class="pull-right" title="Refresh status"><i class="fa fa-refresh"></i></span>
|
||||||
|
<hr>
|
||||||
|
<button ng-disabled="status=='running'" class="btn btn-primary" ng-click="cAction('start')"><i class="fa fa-play"></i> Start</button>
|
||||||
|
<button ng-disabled="status!='running'" class="btn btn-primary" ng-click="cAction('restart')"><i class="fa fa-refresh"></i> Restart</button>
|
||||||
|
<button ng-disabled="status!='running'" class="btn btn-primary" ng-click="cAction('stop')"><i class="fa fa-stop"></i> Stop</button>
|
||||||
|
<button class="btn btn-block btn-primary" ng-click="cRemove()">Remove</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="panel">
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="example-box-wrapper">
|
||||||
|
<h3 class="title-hero" ng-init="rPolicy='{{restartPolicy}}'">Other Actions</h3>
|
||||||
|
<b>Restart on system reboot:</b> <span ng-bind="rPolicy"></span><hr>
|
||||||
|
<a href="/docker/exportContainer/?name={{name}}" class="btn btn-block btn-primary">Export file</a>
|
||||||
|
<button class="btn btn-block btn-primary" ng-disabled="loadingTop" ng-click="showTop()">View Process</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="example-box-wrapper">
|
||||||
|
|
||||||
|
<div class="content-box">
|
||||||
|
|
||||||
|
<h3 class="content-box-header bg-blue" ng-init="loadLogs('{{name}}')">
|
||||||
|
{% trans "Logs" %}
|
||||||
|
<span style="cursor:pointer;" class="pull-right" ng-click="loadLogs('{{name}}')"><i class="fa fa-refresh"></i></span>
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="content-box-wrapper">
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<textarea name="logs" class="form-control" id="" cols="30" rows="10">{$ logs $}</textarea><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div id="settings" class="modal fade" role="dialog">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
|
||||||
|
<!-- Modal content-->
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
<h4 class="modal-title">Container Settings
|
||||||
|
<img id="containerSettingLoading" src="/static/images/loading.gif" style="display: none;">
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<form name="containerSettingsForm" action="/" class="form-horizontal">
|
||||||
|
<div ng-hide="installationDetailsForm" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Memory limit" %}</label>
|
||||||
|
<div class="col-sm-6" ng-init="memory={{memoryLimit}}">
|
||||||
|
<input name="memory" type="number" class="form-control" ng-model="memory" required>
|
||||||
|
</div>
|
||||||
|
<div class="current-pack ng-binding">MB</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="installationDetailsForm" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">Start on reboot</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<div class="checkbox" ng-init="startOnReboot={{startOnReboot}}">
|
||||||
|
<label>
|
||||||
|
<input ng-model="startOnReboot" type="checkbox" value="" class="ng-pristine ng-untouched ng-valid ng-empty">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<div ng-hide="installationDetailsForm" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Confirmation" %}</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input ng-model="envConfirmation" type="checkbox">
|
||||||
|
Editing ENV will recreate container <i class="fa fa-warning" title="If you tick this checkbox, your container will be recreated with saved information. Data saved inside container will be deleted (Not avaialble for container created outside of cyberpanel)"></i>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span ng-init="envList = {}"></span>
|
||||||
|
{% for env, value in envList.items %}
|
||||||
|
|
||||||
|
<span ng-init="envList[{{ forloop.counter0 }}] = {'name':'{{env}}' , 'value':'{{value}}'} "></span>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<div ng-repeat="env in envList track by $index">
|
||||||
|
|
||||||
|
<div ng-hide="installationDetailsForm" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">
|
||||||
|
<div ng-show="$first">
|
||||||
|
{% trans "ENV" %}
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<input name="$index" type="text" class="form-control" ng-model="envList[$index].name" required>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<input name="$index" type="text" class="form-control" ng-model="envList[$index].value" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-offset-3">
|
||||||
|
<button type="button" class="btn btn-info" ng-click="addEnvField()">Add more</button>
|
||||||
|
</div><br>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" ng-disabled="savingSettings" class="btn btn-primary" ng-click="saveSettings()">Save</button>
|
||||||
|
<button type="button" ng-disabled="savingSettings" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="processes" class="modal fade" role="dialog">
|
||||||
|
<div class="modal-dialog" style="width: 96%;">
|
||||||
|
|
||||||
|
<!-- Modal content-->
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
|
<h4 class="modal-title">Container Processes</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="datatable-example">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th ng-repeat="item in topHead track by $index">{$ item $}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<tr ng-repeat="process in topProcesses track by $index">
|
||||||
|
<th ng-repeat="item in process track by $index">{$ item $}</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" ng-disabled="savingSettings" class="btn btn-primary" ng-click="showTop()">Refresh</button>
|
||||||
|
<button type="button" ng-disabled="savingSettings" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
6
dockerManager/tests.py
Normal file
6
dockerManager/tests.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
||||||
29
dockerManager/urls.py
Normal file
29
dockerManager/urls.py
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
from django.conf.urls import url
|
||||||
|
import views
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^$', views.loadDockerHome, name='dockerHome'),
|
||||||
|
# url(r'^images', views.loadImages, name='loadImages'),
|
||||||
|
url(r'^getTags', views.getTags, name='getTags'),
|
||||||
|
url(r'^runContainer', views.runContainer, name='runContainer'),
|
||||||
|
url(r'^submitContainerCreation', views.submitContainerCreation, name='submitContainerCreation'),
|
||||||
|
url(r'^listContainers', views.listContainers, name='listContainers'),
|
||||||
|
url(r'^getContainerList', views.getContainerList, name='getContainerList'),
|
||||||
|
url(r'^getContainerLogs', views.getContainerLogs, name='getContainerLogs'),
|
||||||
|
url(r'^installImage', views.installImage, name='installImage'),
|
||||||
|
url(r'^delContainer', views.delContainer, name='delContainer'),
|
||||||
|
url(r'^doContainerAction', views.doContainerAction, name='doContainerAction'),
|
||||||
|
url(r'^getContainerStatus', views.getContainerStatus, name='getContainerStatus'),
|
||||||
|
url(r'^exportContainer', views.exportContainer, name='exportContainer'),
|
||||||
|
url(r'^saveContainerSettings', views.saveContainerSettings, name='saveContainerSettings'),
|
||||||
|
url(r'^getContainerTop', views.getContainerTop, name='getContainerTop'),
|
||||||
|
url(r'^assignContainer', views.assignContainer, name='assignContainer'),
|
||||||
|
url(r'^searchImage', views.searchImage, name='searchImage'),
|
||||||
|
url(r'^manageImages', views.manageImages, name='manageImages'),
|
||||||
|
url(r'^getImageHistory', views.getImageHistory, name='getImageHistory'),
|
||||||
|
url(r'^removeImage', views.removeImage, name='removeImage'),
|
||||||
|
url(r'^recreateContainer', views.recreateContainer, name='recreateContainer'),
|
||||||
|
url(r'^installDocker', views.installDocker, name='installDocker'),
|
||||||
|
url(r'^images', views.images, name='containerImage'),
|
||||||
|
url(r'^view/(?P<name>(.*))$', views.viewContainer, name='viewContainer'),
|
||||||
|
]
|
||||||
362
dockerManager/views.py
Normal file
362
dockerManager/views.py
Normal file
@@ -0,0 +1,362 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.shortcuts import render,redirect
|
||||||
|
from loginSystem.models import Administrator
|
||||||
|
from loginSystem.views import loadLoginPage
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from plogical.container import ContainerManager
|
||||||
|
from dockerManager.pluginManager import pluginManager
|
||||||
|
from decorators import preDockerRun
|
||||||
|
from plogical.acl import ACLManager
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
import docker
|
||||||
|
|
||||||
|
# Use default socket to connect
|
||||||
|
client = docker.from_env()
|
||||||
|
# Create your views here.
|
||||||
|
|
||||||
|
# This function checks if user has admin permissions
|
||||||
|
def dockerPermission(request, userID, context):
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
|
||||||
|
if currentACL['admin'] != 1:
|
||||||
|
if request.method == "POST":
|
||||||
|
return ACLManager.loadErrorJson()
|
||||||
|
else:
|
||||||
|
return ACLManager.loadError()
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def loadDockerHome(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
admin = Administrator.objects.get(pk=userID)
|
||||||
|
return render(request,'dockerManager/index.html',{"type":admin.type})
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
def installDocker(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
result = pluginManager.preDockerInstallation(request) # Later change to preInstallInstallation
|
||||||
|
|
||||||
|
if result != 200:
|
||||||
|
return result
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.submitInstallDocker(userID, json.loads(request.body))
|
||||||
|
|
||||||
|
result = pluginManager.postDockerInstallation(request, coreResult)
|
||||||
|
if result != 200:
|
||||||
|
return result
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def installImage(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.submitInstallImage(userID, json.loads(request.body))
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def viewContainer(request, name):
|
||||||
|
try:
|
||||||
|
if not request.GET._mutable:
|
||||||
|
request.GET._mutable = True
|
||||||
|
request.GET['name'] = name
|
||||||
|
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
cm = ContainerManager(name)
|
||||||
|
coreResult = cm.loadContainerHome(request, userID)
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def getTags(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.getTags(userID, json.loads(request.body))
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def delContainer(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.submitContainerDeletion(userID, json.loads(request.body))
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def recreateContainer(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.recreateContainer(userID, json.loads(request.body))
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def runContainer(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
return cm.createContainer(request, userID)
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def listContainers(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
return cm.listContainers(request, userID)
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def getContainerLogs(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.getContainerLogs(userID, json.loads(request.body))
|
||||||
|
return coreResult
|
||||||
|
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def submitContainerCreation(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.submitContainerCreation(userID, json.loads(request.body))
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def getContainerList(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
return cm.getContainerList(userID, json.loads(request.body))
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def doContainerAction(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.doContainerAction(userID, json.loads(request.body))
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def getContainerStatus(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.getContainerStatus(userID, json.loads(request.body))
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def exportContainer(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.exportContainer(request, userID)
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def saveContainerSettings(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.saveContainerSettings(userID, json.loads(request.body))
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def getContainerTop(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.getContainerTop(userID, json.loads(request.body))
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def assignContainer(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.assignContainer(userID, json.loads(request.body))
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def searchImage(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.searchImage(userID, json.loads(request.body))
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def images(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'images')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.images(request, userID)
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def manageImages(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.manageImages(request, userID)
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def getImageHistory(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.getImageHistory(userID, json.loads(request.body))
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
|
|
||||||
|
@preDockerRun
|
||||||
|
def removeImage(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
perm = dockerPermission(request, userID, 'loadDockerHome')
|
||||||
|
if perm: return perm
|
||||||
|
|
||||||
|
cm = ContainerManager()
|
||||||
|
coreResult = cm.removeImage(userID, json.loads(request.body))
|
||||||
|
|
||||||
|
return coreResult
|
||||||
|
except KeyError:
|
||||||
|
return redirect(loadLoginPage)
|
||||||
87
emailMarketing/migrations/0001_initial.py
Normal file
87
emailMarketing/migrations/0001_initial.py
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2019-01-07 12:43
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('websiteFunctions', '0001_initial'),
|
||||||
|
('loginSystem', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EmailJobs',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('date', models.CharField(max_length=200)),
|
||||||
|
('host', models.CharField(max_length=1000)),
|
||||||
|
('totalEmails', models.IntegerField()),
|
||||||
|
('sent', models.IntegerField()),
|
||||||
|
('failed', models.IntegerField()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EmailLists',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('listName', models.CharField(max_length=50, unique=True)),
|
||||||
|
('dateCreated', models.CharField(max_length=200)),
|
||||||
|
('owner', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='websiteFunctions.Websites')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EmailMarketing',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('userName', models.CharField(max_length=50, unique=True)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EmailsInList',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('email', models.CharField(max_length=50)),
|
||||||
|
('firstName', models.CharField(default='', max_length=20)),
|
||||||
|
('lastName', models.CharField(default='', max_length=20)),
|
||||||
|
('verificationStatus', models.CharField(max_length=100)),
|
||||||
|
('dateCreated', models.CharField(max_length=200)),
|
||||||
|
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='emailMarketing.EmailLists')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EmailTemplate',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=100, unique=True)),
|
||||||
|
('subject', models.CharField(max_length=1000)),
|
||||||
|
('fromName', models.CharField(max_length=100)),
|
||||||
|
('fromEmail', models.CharField(max_length=150)),
|
||||||
|
('replyTo', models.CharField(max_length=150)),
|
||||||
|
('emailMessage', models.CharField(max_length=3000000)),
|
||||||
|
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='loginSystem.Administrator')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SMTPHosts',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('host', models.CharField(max_length=150, unique=True)),
|
||||||
|
('port', models.CharField(max_length=10)),
|
||||||
|
('userName', models.CharField(max_length=50)),
|
||||||
|
('password', models.CharField(max_length=50)),
|
||||||
|
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='loginSystem.Administrator')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='emailjobs',
|
||||||
|
name='owner',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='emailMarketing.EmailTemplate'),
|
||||||
|
),
|
||||||
|
]
|
||||||
50
emailPremium/migrations/0001_initial.py
Normal file
50
emailPremium/migrations/0001_initial.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2019-01-07 12:43
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('mailServer', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='DomainLimits',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('limitStatus', models.IntegerField(default=0)),
|
||||||
|
('monthlyLimit', models.IntegerField(default=10000)),
|
||||||
|
('monthlyUsed', models.IntegerField(default=0)),
|
||||||
|
('domain', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mailServer.Domains')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EmailLimits',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('limitStatus', models.IntegerField(default=0)),
|
||||||
|
('monthlyLimits', models.IntegerField(default=2000)),
|
||||||
|
('monthlyUsed', models.IntegerField(default=0)),
|
||||||
|
('hourlyLimit', models.IntegerField(default=50)),
|
||||||
|
('hourlyUsed', models.IntegerField(default=0)),
|
||||||
|
('emailLogs', models.IntegerField(default=0)),
|
||||||
|
('email', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mailServer.EUsers')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EmailLogs',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('destination', models.CharField(max_length=200)),
|
||||||
|
('timeStamp', models.CharField(max_length=200)),
|
||||||
|
('email', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mailServer.EUsers')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
26
firewall/migrations/0001_initial.py
Normal file
26
firewall/migrations/0001_initial.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2019-01-07 12:43
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='FirewallRules',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=32, unique=True)),
|
||||||
|
('proto', models.CharField(max_length=10)),
|
||||||
|
('port', models.CharField(max_length=25)),
|
||||||
|
('ipAddress', models.CharField(default=b'0.0.0.0/0', max_length=30)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
39
ftp/migrations/0001_initial.py
Normal file
39
ftp/migrations/0001_initial.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2019-01-07 12:43
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('websiteFunctions', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Users',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(db_column=b'ID', primary_key=True, serialize=False)),
|
||||||
|
('user', models.CharField(db_column=b'User', max_length=32, unique=True)),
|
||||||
|
('password', models.CharField(db_column=b'Password', max_length=64)),
|
||||||
|
('uid', models.IntegerField(db_column=b'Uid')),
|
||||||
|
('gid', models.IntegerField(db_column=b'Gid')),
|
||||||
|
('dir', models.CharField(db_column=b'Dir', max_length=255)),
|
||||||
|
('quotasize', models.IntegerField(db_column=b'QuotaSize')),
|
||||||
|
('status', models.CharField(db_column=b'Status', max_length=1)),
|
||||||
|
('ulbandwidth', models.IntegerField(db_column=b'ULBandwidth')),
|
||||||
|
('dlbandwidth', models.IntegerField(db_column=b'DLBandwidth')),
|
||||||
|
('date', models.DateField(db_column=b'Date')),
|
||||||
|
('lastmodif', models.CharField(db_column=b'LastModif', max_length=255)),
|
||||||
|
('domain', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='websiteFunctions.Websites')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'users',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
76
loginSystem/migrations/0001_initial.py
Normal file
76
loginSystem/migrations/0001_initial.py
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2019-01-07 12:43
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ACL',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=50, unique=True)),
|
||||||
|
('adminStatus', models.IntegerField(default=0)),
|
||||||
|
('versionManagement', models.IntegerField(default=0)),
|
||||||
|
('createNewUser', models.IntegerField(default=0)),
|
||||||
|
('deleteUser', models.IntegerField(default=0)),
|
||||||
|
('resellerCenter', models.IntegerField(default=0)),
|
||||||
|
('changeUserACL', models.IntegerField(default=0)),
|
||||||
|
('createWebsite', models.IntegerField(default=0)),
|
||||||
|
('modifyWebsite', models.IntegerField(default=0)),
|
||||||
|
('suspendWebsite', models.IntegerField(default=0)),
|
||||||
|
('deleteWebsite', models.IntegerField(default=0)),
|
||||||
|
('createPackage', models.IntegerField(default=0)),
|
||||||
|
('deletePackage', models.IntegerField(default=0)),
|
||||||
|
('modifyPackage', models.IntegerField(default=0)),
|
||||||
|
('createDatabase', models.IntegerField(default=1)),
|
||||||
|
('deleteDatabase', models.IntegerField(default=1)),
|
||||||
|
('listDatabases', models.IntegerField(default=1)),
|
||||||
|
('createNameServer', models.IntegerField(default=0)),
|
||||||
|
('createDNSZone', models.IntegerField(default=1)),
|
||||||
|
('deleteZone', models.IntegerField(default=1)),
|
||||||
|
('addDeleteRecords', models.IntegerField(default=1)),
|
||||||
|
('createEmail', models.IntegerField(default=1)),
|
||||||
|
('deleteEmail', models.IntegerField(default=1)),
|
||||||
|
('emailForwarding', models.IntegerField(default=1)),
|
||||||
|
('changeEmailPassword', models.IntegerField(default=1)),
|
||||||
|
('dkimManager', models.IntegerField(default=1)),
|
||||||
|
('createFTPAccount', models.IntegerField(default=1)),
|
||||||
|
('deleteFTPAccount', models.IntegerField(default=1)),
|
||||||
|
('listFTPAccounts', models.IntegerField(default=1)),
|
||||||
|
('createBackup', models.IntegerField(default=1)),
|
||||||
|
('restoreBackup', models.IntegerField(default=0)),
|
||||||
|
('addDeleteDestinations', models.IntegerField(default=0)),
|
||||||
|
('scheDuleBackups', models.IntegerField(default=0)),
|
||||||
|
('remoteBackups', models.IntegerField(default=0)),
|
||||||
|
('manageSSL', models.IntegerField(default=1)),
|
||||||
|
('hostnameSSL', models.IntegerField(default=0)),
|
||||||
|
('mailServerSSL', models.IntegerField(default=0)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Administrator',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('userName', models.CharField(max_length=50, unique=True)),
|
||||||
|
('password', models.CharField(max_length=200)),
|
||||||
|
('firstName', models.CharField(default='None', max_length=20)),
|
||||||
|
('lastName', models.CharField(default='None', max_length=20)),
|
||||||
|
('email', models.CharField(max_length=50)),
|
||||||
|
('type', models.IntegerField()),
|
||||||
|
('owner', models.IntegerField(default=1)),
|
||||||
|
('token', models.CharField(default='None', max_length=500)),
|
||||||
|
('initWebsitesLimit', models.IntegerField(default=0)),
|
||||||
|
('acl', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='loginSystem.ACL')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
61
mailServer/migrations/0001_initial.py
Normal file
61
mailServer/migrations/0001_initial.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2019-01-07 12:43
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('websiteFunctions', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Domains',
|
||||||
|
fields=[
|
||||||
|
('domain', models.CharField(max_length=50, primary_key=True, serialize=False)),
|
||||||
|
('domainOwner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='websiteFunctions.Websites')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'e_domains',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EUsers',
|
||||||
|
fields=[
|
||||||
|
('email', models.CharField(max_length=80, primary_key=True, serialize=False)),
|
||||||
|
('password', models.CharField(max_length=20)),
|
||||||
|
('emailOwner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mailServer.Domains')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'e_users',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Forwardings',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('source', models.CharField(max_length=80)),
|
||||||
|
('destination', models.TextField()),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'e_forwardings',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Transport',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('domain', models.CharField(max_length=128, unique=True)),
|
||||||
|
('transport', models.CharField(max_length=128)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'e_transport',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
38
managePHP/migrations/0001_initial.py
Normal file
38
managePHP/migrations/0001_initial.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2019-01-07 12:43
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='installedPackages',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('extensionName', models.CharField(max_length=50)),
|
||||||
|
('description', models.CharField(max_length=255)),
|
||||||
|
('status', models.IntegerField()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='PHP',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('phpVers', models.CharField(max_length=5, unique=True)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='installedpackages',
|
||||||
|
name='phpVers',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='managePHP.PHP'),
|
||||||
|
),
|
||||||
|
]
|
||||||
32
packages/migrations/0001_initial.py
Normal file
32
packages/migrations/0001_initial.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2019-01-07 12:43
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('loginSystem', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Package',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('packageName', models.CharField(max_length=50, unique=True)),
|
||||||
|
('diskSpace', models.IntegerField()),
|
||||||
|
('bandwidth', models.IntegerField()),
|
||||||
|
('emailAccounts', models.IntegerField(null=True)),
|
||||||
|
('dataBases', models.IntegerField(default=0)),
|
||||||
|
('ftpAccounts', models.IntegerField(default=0)),
|
||||||
|
('allowedDomains', models.IntegerField(default=0)),
|
||||||
|
('admin', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='loginSystem.Administrator')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -8,6 +8,7 @@ from loginSystem.models import Administrator, ACL
|
|||||||
from django.shortcuts import HttpResponse
|
from django.shortcuts import HttpResponse
|
||||||
from packages.models import Package
|
from packages.models import Package
|
||||||
from websiteFunctions.models import Websites, ChildDomains
|
from websiteFunctions.models import Websites, ChildDomains
|
||||||
|
from dockerManager.models import Containers
|
||||||
from dns.models import Domains
|
from dns.models import Domains
|
||||||
import json
|
import json
|
||||||
from subprocess import call, CalledProcessError
|
from subprocess import call, CalledProcessError
|
||||||
@@ -104,6 +105,9 @@ class ACLManager:
|
|||||||
finalResponse['manageSSL'] = acl.manageSSL
|
finalResponse['manageSSL'] = acl.manageSSL
|
||||||
finalResponse['hostnameSSL'] = acl.hostnameSSL
|
finalResponse['hostnameSSL'] = acl.hostnameSSL
|
||||||
finalResponse['mailServerSSL'] = acl.mailServerSSL
|
finalResponse['mailServerSSL'] = acl.mailServerSSL
|
||||||
|
|
||||||
|
# Container Management
|
||||||
|
finalResponse['assignContainer'] = acl.assignContainer
|
||||||
|
|
||||||
return finalResponse
|
return finalResponse
|
||||||
|
|
||||||
@@ -230,24 +234,6 @@ class ACLManager:
|
|||||||
adminNames.append(admin.userName)
|
adminNames.append(admin.userName)
|
||||||
return adminNames
|
return adminNames
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def loadUserObjects(userID):
|
|
||||||
admin = Administrator.objects.get(pk=userID)
|
|
||||||
adminObjects = []
|
|
||||||
|
|
||||||
finalResponse = ACLManager.loadedACL(userID)
|
|
||||||
|
|
||||||
if finalResponse['admin'] == 1:
|
|
||||||
return Administrator.objects.all()
|
|
||||||
else:
|
|
||||||
admins = Administrator.objects.filter(owner=admin.pk)
|
|
||||||
for items in admins:
|
|
||||||
adminObjects.append(items)
|
|
||||||
|
|
||||||
adminObjects.append(admin)
|
|
||||||
|
|
||||||
return adminObjects
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def loadDeletionUsers(userID, finalResponse):
|
def loadDeletionUsers(userID, finalResponse):
|
||||||
admin = Administrator.objects.get(pk=userID)
|
admin = Administrator.objects.get(pk=userID)
|
||||||
@@ -329,15 +315,6 @@ class ACLManager:
|
|||||||
|
|
||||||
return packNames
|
return packNames
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def loadPackageObjects(userID, finalResponse):
|
|
||||||
admin = Administrator.objects.get(pk=userID)
|
|
||||||
|
|
||||||
if finalResponse['admin'] == 1:
|
|
||||||
return Package.objects.all()
|
|
||||||
else:
|
|
||||||
return admin.package_set.all()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def findAllSites(currentACL, userID):
|
def findAllSites(currentACL, userID):
|
||||||
websiteNames = []
|
websiteNames = []
|
||||||
@@ -362,6 +339,30 @@ class ACLManager:
|
|||||||
|
|
||||||
|
|
||||||
return websiteNames
|
return websiteNames
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def findAllContainers(currentACL, userID):
|
||||||
|
containerName = []
|
||||||
|
|
||||||
|
if currentACL['admin'] == 1:
|
||||||
|
allContainers = Containers.objects.all()
|
||||||
|
for items in allContainers:
|
||||||
|
containerName.append(items.name)
|
||||||
|
else:
|
||||||
|
admin = Administrator.objects.get(pk=userID)
|
||||||
|
|
||||||
|
containers = admin.containers_set.all()
|
||||||
|
admins = Administrator.objects.filter(owner=admin.pk)
|
||||||
|
|
||||||
|
for items in containers:
|
||||||
|
containerName.append(items.name)
|
||||||
|
|
||||||
|
for items in admins:
|
||||||
|
cons = items.containers_set.all()
|
||||||
|
for con in cons:
|
||||||
|
containerName.append(con.name)
|
||||||
|
|
||||||
|
return containerName
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def findWebsiteObjects(currentACL, userID):
|
def findWebsiteObjects(currentACL, userID):
|
||||||
@@ -386,6 +387,30 @@ class ACLManager:
|
|||||||
websiteList.append(web)
|
websiteList.append(web)
|
||||||
|
|
||||||
return websiteList
|
return websiteList
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def findContainersObjects(currentACL, userID):
|
||||||
|
|
||||||
|
if currentACL['admin'] == 1:
|
||||||
|
return Containers.objects.all()
|
||||||
|
else:
|
||||||
|
|
||||||
|
containerList = []
|
||||||
|
admin = Administrator.objects.get(pk=userID)
|
||||||
|
|
||||||
|
containers = admin.containers_set.all()
|
||||||
|
|
||||||
|
for items in containers:
|
||||||
|
containerList.append(items)
|
||||||
|
|
||||||
|
admins = Administrator.objects.filter(owner=admin.pk)
|
||||||
|
|
||||||
|
for items in admins:
|
||||||
|
cons = items.containers_set.all()
|
||||||
|
for con in cons:
|
||||||
|
containerList.append(web)
|
||||||
|
|
||||||
|
return containerList
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def findAllDomains(currentACL, userID):
|
def findAllDomains(currentACL, userID):
|
||||||
@@ -437,6 +462,22 @@ class ACLManager:
|
|||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def checkContainerOwnership(name, userID):
|
||||||
|
try:
|
||||||
|
container = Containers.objects.get(name=name)
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
admin = Administrator.objects.get(pk=userID)
|
||||||
|
|
||||||
|
if currentACL['admin'] == 1:
|
||||||
|
return 1
|
||||||
|
elif container.admin == admin:
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
except:
|
||||||
|
return 0
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def executeCall(command):
|
def executeCall(command):
|
||||||
|
|||||||
938
plogical/container.py
Normal file
938
plogical/container.py
Normal file
@@ -0,0 +1,938 @@
|
|||||||
|
#!/usr/local/CyberCP/bin/python2
|
||||||
|
from __future__ import division
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
import sys
|
||||||
|
import django
|
||||||
|
import mimetypes
|
||||||
|
sys.path.append('/usr/local/CyberCP')
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
|
||||||
|
django.setup()
|
||||||
|
import json
|
||||||
|
from acl import ACLManager
|
||||||
|
import CyberCPLogFileWriter as logging
|
||||||
|
from django.shortcuts import HttpResponse, render
|
||||||
|
from loginSystem.models import Administrator, ACL
|
||||||
|
import subprocess
|
||||||
|
import shlex
|
||||||
|
import time
|
||||||
|
from dockerManager.models import Containers
|
||||||
|
from django.http import StreamingHttpResponse
|
||||||
|
from wsgiref.util import FileWrapper
|
||||||
|
from math import ceil
|
||||||
|
import docker
|
||||||
|
import docker.utils
|
||||||
|
import requests
|
||||||
|
|
||||||
|
# Use default socket to connect
|
||||||
|
client = docker.from_env()
|
||||||
|
dockerAPI = docker.APIClient()
|
||||||
|
|
||||||
|
class ContainerManager:
|
||||||
|
def __init__(self, name = None):
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def submitInstallDocker(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
if ACLManager.currentContextPermission(currentACL, 'createContainer') == 0:
|
||||||
|
return ACLManager.loadError()
|
||||||
|
|
||||||
|
command = 'yum install -y docker'
|
||||||
|
cmd = shlex.split(command)
|
||||||
|
res = subprocess.call(cmd)
|
||||||
|
|
||||||
|
if res == 0:
|
||||||
|
data_ret = {'installDockerStatus': 1, 'error_message': 'None'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
else:
|
||||||
|
data_ret = {'installDockerStatus': 0, 'error_message': 'Failed to install. Manual install required.'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
return HttpResponse(res)
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
return HttpResponse(str(msg))
|
||||||
|
|
||||||
|
def createContainer(self, request = None, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
if ACLManager.currentContextPermission(currentACL, 'createContainer') == 0:
|
||||||
|
return ACLManager.loadError()
|
||||||
|
|
||||||
|
adminNames = ACLManager.loadAllUsers(userID)
|
||||||
|
tag = request.GET.get('tag')
|
||||||
|
image = request.GET.get('image')
|
||||||
|
tag = tag.split(" (")[0]
|
||||||
|
|
||||||
|
if "/" in image:
|
||||||
|
name = image.split("/")[0] + "." + image.split("/")[1]
|
||||||
|
else:
|
||||||
|
name = image
|
||||||
|
|
||||||
|
try:
|
||||||
|
inspectImage = dockerAPI.inspect_image(image+":"+tag)
|
||||||
|
except docker.errors.ImageNotFound:
|
||||||
|
val = request.session['userID']
|
||||||
|
admin = Administrator.objects.get(pk=val)
|
||||||
|
return render(request,'dockerManager/images.html',{"type":admin.type,
|
||||||
|
'image':image,
|
||||||
|
'tag':tag})
|
||||||
|
|
||||||
|
envList = {};
|
||||||
|
if 'Env' in inspectImage['Config']:
|
||||||
|
for item in inspectImage['Config']['Env']:
|
||||||
|
if '=' in item:
|
||||||
|
splitedItem = item.split('=',1)
|
||||||
|
print splitedItem
|
||||||
|
envList[splitedItem[0]] = splitedItem[1]
|
||||||
|
else:
|
||||||
|
envList[item] = ""
|
||||||
|
|
||||||
|
portConfig = {};
|
||||||
|
if 'ExposedPorts' in inspectImage['Config']:
|
||||||
|
for item in inspectImage['Config']['ExposedPorts']:
|
||||||
|
portDef = item.split('/')
|
||||||
|
portConfig[portDef[0]] = portDef[1]
|
||||||
|
|
||||||
|
print portConfig
|
||||||
|
if image is None or image is '' or tag is None or tag is '':
|
||||||
|
return redirect(loadImages)
|
||||||
|
|
||||||
|
Data = {"ownerList": adminNames, "image":image, "name":name, "tag":tag, "portConfig": portConfig, "envList":envList}
|
||||||
|
|
||||||
|
return render(request, 'dockerManager/runContainer.html', Data)
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
return HttpResponse(str(msg))
|
||||||
|
|
||||||
|
def loadContainerHome(self, request = None, userID = None, data = None):
|
||||||
|
name = self.name
|
||||||
|
|
||||||
|
if ACLManager.checkContainerOwnership(name, userID) != 1:
|
||||||
|
return ACLManager.loadError()
|
||||||
|
|
||||||
|
try:
|
||||||
|
container = client.containers.get(name)
|
||||||
|
except docker.errors.NotFound as err:
|
||||||
|
return HttpResponse("Container not found")
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
con = Containers.objects.get(name=name)
|
||||||
|
data['name'] = name
|
||||||
|
data['image'] = con.image + ":" + con.tag
|
||||||
|
data['ports'] = json.loads(con.ports)
|
||||||
|
data['cid'] = con.cid
|
||||||
|
data['envList'] = json.loads(con.env)
|
||||||
|
print data['envList']
|
||||||
|
|
||||||
|
stats = container.stats(decode=False, stream=False)
|
||||||
|
logs = container.logs(stream=True)
|
||||||
|
|
||||||
|
data['status'] = container.status
|
||||||
|
data['memoryLimit'] = con.memory
|
||||||
|
if con.startOnReboot == 1:
|
||||||
|
data['startOnReboot'] = 'true'
|
||||||
|
data['restartPolicy'] = "Yes"
|
||||||
|
else:
|
||||||
|
data['startOnReboot'] = 'false'
|
||||||
|
data['restartPolicy'] = "No"
|
||||||
|
|
||||||
|
if 'usage' in stats['memory_stats']:
|
||||||
|
# Calculate Usage
|
||||||
|
# Source: https://github.com/docker/docker/blob/28a7577a029780e4533faf3d057ec9f6c7a10948/api/client/stats.go#L309
|
||||||
|
data['memoryUsage'] = (stats['memory_stats']['usage'] / stats['memory_stats']['limit']) * 100
|
||||||
|
|
||||||
|
cpu_count = len(stats["cpu_stats"]["cpu_usage"]["percpu_usage"])
|
||||||
|
data['cpuUsage'] = 0.0
|
||||||
|
cpu_delta = float(stats["cpu_stats"]["cpu_usage"]["total_usage"]) - \
|
||||||
|
float(stats["precpu_stats"]["cpu_usage"]["total_usage"])
|
||||||
|
system_delta = float(stats["cpu_stats"]["system_cpu_usage"]) - \
|
||||||
|
float(stats["precpu_stats"]["system_cpu_usage"])
|
||||||
|
if system_delta > 0.0:
|
||||||
|
data['cpuUsage'] = round(cpu_delta / system_delta * 100.0 * cpu_count, 3)
|
||||||
|
else:
|
||||||
|
data['memoryUsage'] = 0
|
||||||
|
data['cpuUsage'] = 0;
|
||||||
|
|
||||||
|
return render(request, 'dockerManager/viewContainer.html', data)
|
||||||
|
|
||||||
|
def listContainers(self, request = None, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
containers = ACLManager.findAllContainers(currentACL, userID)
|
||||||
|
|
||||||
|
allContainers = client.containers.list()
|
||||||
|
containersList = []
|
||||||
|
showUnlistedContainer = True
|
||||||
|
|
||||||
|
# TODO: Add condition to show unlisted Containers only if user has admin level access
|
||||||
|
|
||||||
|
unlistedContainers = []
|
||||||
|
for container in allContainers:
|
||||||
|
if container.name not in containers:
|
||||||
|
unlistedContainers.append(container)
|
||||||
|
|
||||||
|
if not unlistedContainers:
|
||||||
|
showUnlistedContainer = False
|
||||||
|
|
||||||
|
adminNames = ACLManager.loadAllUsers(userID)
|
||||||
|
|
||||||
|
pages = float(len(containers)) / float(10)
|
||||||
|
pagination = []
|
||||||
|
|
||||||
|
if pages <= 1.0:
|
||||||
|
pages = 1
|
||||||
|
pagination.append('<li><a href="\#"></a></li>')
|
||||||
|
else:
|
||||||
|
pages = ceil(pages)
|
||||||
|
finalPages = int(pages) + 1
|
||||||
|
|
||||||
|
for i in range(1, finalPages):
|
||||||
|
pagination.append('<li><a href="\#">' + str(i) + '</a></li>')
|
||||||
|
|
||||||
|
return render(request, 'dockerManager/listContainers.html', {"pagination": pagination,
|
||||||
|
"unlistedContainers": unlistedContainers,
|
||||||
|
"adminNames": adminNames,
|
||||||
|
"showUnlistedContainer":showUnlistedContainer})
|
||||||
|
except BaseException, msg:
|
||||||
|
return HttpResponse(str(msg))
|
||||||
|
|
||||||
|
def getContainerLogs(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
name = data['name']
|
||||||
|
|
||||||
|
# Check if container is registered in database or unlisted
|
||||||
|
if Containers.objects.filter(name=name).exists():
|
||||||
|
if ACLManager.checkContainerOwnership(name, userID) != 1:
|
||||||
|
return ACLManager.loadErrorJson('containerLogStatus',0)
|
||||||
|
|
||||||
|
container = client.containers.get(name)
|
||||||
|
logs = container.logs()
|
||||||
|
|
||||||
|
data_ret = {'containerLogStatus': 1, 'containerLog': logs, 'error_message': "None"}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
data_ret = {'containerLogStatus': 0, 'containerLog':'Error', 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def submitContainerCreation(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
if ACLManager.currentContextPermission(currentACL, 'createWebsite') == 0:
|
||||||
|
return ACLManager.loadErrorJson('createWebSiteStatus', 0)
|
||||||
|
|
||||||
|
name = data['name']
|
||||||
|
image = data['image']
|
||||||
|
tag = data['tag']
|
||||||
|
dockerOwner = data['dockerOwner']
|
||||||
|
memory = data['memory']
|
||||||
|
envList = data['envList']
|
||||||
|
|
||||||
|
inspectImage = dockerAPI.inspect_image(image+":"+tag)
|
||||||
|
portConfig = {}
|
||||||
|
|
||||||
|
# Formatting envList for usage
|
||||||
|
envDict = {}
|
||||||
|
for key, value in envList.iteritems():
|
||||||
|
if (value['name'] != '') or (value['value'] != ''):
|
||||||
|
envDict[value['name']] = value['value']
|
||||||
|
|
||||||
|
if 'ExposedPorts' in inspectImage['Config']:
|
||||||
|
for item in inspectImage['Config']['ExposedPorts']:
|
||||||
|
# Do not allow priviledged port numbers
|
||||||
|
if int(data[item]) < 1024 or int(data[item]) > 65535:
|
||||||
|
data_ret = {'createContainerStatus': 0, 'error_message': "Choose port between 1024 and 65535"}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
portConfig[item] = data[item]
|
||||||
|
|
||||||
|
## Create Configurations
|
||||||
|
admin = Administrator.objects.get(userName=dockerOwner)
|
||||||
|
|
||||||
|
containerArgs = {'image':image+":"+tag,
|
||||||
|
'detach':True,
|
||||||
|
'name':name,
|
||||||
|
'ports':portConfig,
|
||||||
|
'publish_all_ports': True,
|
||||||
|
'environment':envDict}
|
||||||
|
|
||||||
|
containerArgs['mem_limit'] = memory * 1048576; # Converts MB to bytes ( 0 * x = 0 for unlimited memory)
|
||||||
|
|
||||||
|
try:
|
||||||
|
container = client.containers.create(**containerArgs)
|
||||||
|
except Exception as err:
|
||||||
|
if "port is already allocated" in err: # We need to delete container if port is not available
|
||||||
|
print "Deleting container"
|
||||||
|
container.remove(force=True)
|
||||||
|
data_ret = {'createContainerStatus': 0, 'error_message': str(err)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
con = Containers(admin=admin,
|
||||||
|
name=name,
|
||||||
|
tag=tag,
|
||||||
|
image=image,
|
||||||
|
memory=memory,
|
||||||
|
ports=json.dumps(portConfig),
|
||||||
|
env=json.dumps(envDict),
|
||||||
|
cid=container.id)
|
||||||
|
|
||||||
|
con.save()
|
||||||
|
|
||||||
|
data_ret = {'createContainerStatus': 1, 'error_message': "None"}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
data_ret = {'createContainerStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def submitInstallImage(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
if ACLManager.currentContextPermission(currentACL, 'createWebsite') == 0:
|
||||||
|
return ACLManager.loadErrorJson('createWebSiteStatus', 0)
|
||||||
|
|
||||||
|
image = data['image']
|
||||||
|
tag = data['tag']
|
||||||
|
|
||||||
|
try:
|
||||||
|
inspectImage = dockerAPI.inspect_image(image+":"+tag)
|
||||||
|
data_ret = {'installImageStatus': 0, 'error_message': "Image already installed"}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
except docker.errors.ImageNotFound:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
image = client.images.pull(image, tag=tag)
|
||||||
|
print image.id
|
||||||
|
except docker.errors.APIError as msg:
|
||||||
|
data_ret = {'installImageStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
|
||||||
|
data_ret = {'installImageStatus': 1, 'error_message': "None"}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
data_ret = {'installImageStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def submitContainerDeletion(self, userID = None, data = None, called = False):
|
||||||
|
try:
|
||||||
|
name = data['name']
|
||||||
|
# Check if container is registered in database or unlisted
|
||||||
|
if Containers.objects.filter(name=name).exists():
|
||||||
|
if ACLManager.checkContainerOwnership(name, userID) != 1:
|
||||||
|
if called:
|
||||||
|
return 'Permission error'
|
||||||
|
else:
|
||||||
|
return ACLManager.loadErrorJson('websiteDeleteStatus', 0)
|
||||||
|
|
||||||
|
unlisted = data['unlisted']
|
||||||
|
|
||||||
|
if 'force' in data:
|
||||||
|
force = True
|
||||||
|
else:
|
||||||
|
force = False
|
||||||
|
|
||||||
|
if not unlisted:
|
||||||
|
containerOBJ = Containers.objects.get(name=name)
|
||||||
|
|
||||||
|
if not force:
|
||||||
|
try:
|
||||||
|
container = client.containers.get(name)
|
||||||
|
except docker.errors.NotFound as err:
|
||||||
|
if called:
|
||||||
|
return 'Container does not exist'
|
||||||
|
else:
|
||||||
|
data_ret = {'delContainerStatus': 2, 'error_message': 'Container does not exist'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
try:
|
||||||
|
container.stop() # Stop container
|
||||||
|
container.kill() # INCASE graceful stop doesn't work
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
container.remove() # Finally remove container
|
||||||
|
except docker.errors.APIError as err:
|
||||||
|
data_ret = {'delContainerStatus': 0, 'error_message': str(err)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
except:
|
||||||
|
if called:
|
||||||
|
return "Unknown"
|
||||||
|
else:
|
||||||
|
data_ret = {'delContainerStatus': 0, 'error_message': 'Unknown error'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
if not unlisted and not called:
|
||||||
|
containerOBJ.delete()
|
||||||
|
|
||||||
|
if called:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
data_ret = {'delContainerStatus': 1, 'error_message': "None"}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
if called:
|
||||||
|
return str(msg)
|
||||||
|
else:
|
||||||
|
data_ret = {'delContainerStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def getContainerList(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
pageNumber = int(data['page'])
|
||||||
|
json_data = self.findContainersJson(currentACL, userID, pageNumber)
|
||||||
|
final_dic = {'listContainerStatus': 1, 'error_message': "None", "data": json_data}
|
||||||
|
final_json = json.dumps(final_dic)
|
||||||
|
return HttpResponse(final_json)
|
||||||
|
except BaseException, msg:
|
||||||
|
dic = {'listContainerStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(dic)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def findContainersJson(self, currentACL, userID, pageNumber):
|
||||||
|
finalPageNumber = ((pageNumber * 10)) - 10
|
||||||
|
endPageNumber = finalPageNumber + 10
|
||||||
|
containers = ACLManager.findContainersObjects(currentACL, userID)[finalPageNumber:endPageNumber]
|
||||||
|
|
||||||
|
json_data = "["
|
||||||
|
checker = 0
|
||||||
|
|
||||||
|
for items in containers:
|
||||||
|
dic = {'name': items.name,'admin': items.admin.userName, 'tag':items.tag, 'image':items.image}
|
||||||
|
|
||||||
|
if checker == 0:
|
||||||
|
json_data = json_data + json.dumps(dic)
|
||||||
|
checker = 1
|
||||||
|
else:
|
||||||
|
json_data = json_data + ',' + json.dumps(dic)
|
||||||
|
|
||||||
|
json_data = json_data + ']'
|
||||||
|
|
||||||
|
return json_data
|
||||||
|
|
||||||
|
def doContainerAction(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
|
||||||
|
name = data['name']
|
||||||
|
if ACLManager.checkContainerOwnership(name, userID) != 1:
|
||||||
|
return ACLManager.loadErrorJson('containerActionStatus',0)
|
||||||
|
|
||||||
|
action = data['action']
|
||||||
|
try:
|
||||||
|
container = client.containers.get(name)
|
||||||
|
except docker.errors.NotFound as err:
|
||||||
|
data_ret = {'containerActionStatus': 0, 'error_message': 'Container does not exist'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
except:
|
||||||
|
data_ret = {'containerActionStatus': 0, 'error_message': 'Unknown'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if action == 'start':
|
||||||
|
container.start()
|
||||||
|
elif action == 'stop':
|
||||||
|
container.stop()
|
||||||
|
elif action == 'restart':
|
||||||
|
container.restart()
|
||||||
|
else:
|
||||||
|
data_ret = {'containerActionStatus': 0, 'error_message': 'Unknown Action'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
except docker.errors.APIError as err:
|
||||||
|
data_ret = {'containerActionStatus': 0, 'error_message': str(err)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
time.sleep(3) # Wait 3 seconds for container to finish starting/stopping/restarting
|
||||||
|
status = container.status
|
||||||
|
data_ret = {'containerActionStatus': 1, 'error_message': 'None', 'status': status}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
data_ret = {'containerActionStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def getContainerStatus(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
name = data['name']
|
||||||
|
if ACLManager.checkContainerOwnership(name, userID) != 1:
|
||||||
|
return ACLManager.loadErrorJson('containerStatus',0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
container = client.containers.get(name)
|
||||||
|
except docker.errors.NotFound as err:
|
||||||
|
data_ret = {'containerStatus': 0, 'error_message': 'Container does not exist'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
except:
|
||||||
|
data_ret = {'containerStatus': 0, 'error_message': 'Unknown'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
status = container.status
|
||||||
|
data_ret = {'containerStatus': 1, 'error_message': 'None', 'status': status}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
data_ret = {'containerStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def exportContainer(self, request = None, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
name = request.GET.get('name')
|
||||||
|
if ACLManager.checkContainerOwnership(name, userID) != 1:
|
||||||
|
return ACLManager.loadErrorJson('containerStatus',0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
container = client.containers.get(name)
|
||||||
|
except docker.errors.NotFound as err:
|
||||||
|
data_ret = {'containerStatus': 0, 'error_message': 'Container does not exist'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
except:
|
||||||
|
data_ret = {'containerStatus': 0, 'error_message': 'Unknown'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
eFile = container.export() # Export with default chunk size
|
||||||
|
response = HttpResponse(eFile, content_type='application/force-download')
|
||||||
|
response['Content-Disposition'] = 'attachment; filename="'+ name +'.tar"'
|
||||||
|
return response
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
data_ret = {'containerStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def getContainerTop(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
name = data['name']
|
||||||
|
if ACLManager.checkContainerOwnership(name, userID) != 1:
|
||||||
|
return ACLManager.loadErrorJson('containerTopStatus',0)
|
||||||
|
try:
|
||||||
|
container = client.containers.get(name)
|
||||||
|
except docker.errors.NotFound as err:
|
||||||
|
data_ret = {'containerTopStatus': 0, 'error_message': 'Container does not exist'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
except:
|
||||||
|
data_ret = {'containerTopStatus': 0, 'error_message': 'Unknown'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
try:
|
||||||
|
top = container.top()
|
||||||
|
except docker.errors.APIError as err:
|
||||||
|
data_ret = {'containerTopStatus': 0, 'error_message': str(err)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
data_ret = {'containerTopStatus': 1, 'error_message': 'None', 'processes':top}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
data_ret = {'containerTopStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def assignContainer(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
# Todo: add check only for super user i.e. main admin
|
||||||
|
name = data['name']
|
||||||
|
dockerOwner = data['admin']
|
||||||
|
|
||||||
|
admin = Administrator.objects.get(userName=dockerOwner)
|
||||||
|
|
||||||
|
try:
|
||||||
|
container = client.containers.get(name)
|
||||||
|
except docker.errors.NotFound as err:
|
||||||
|
data_ret = {'assignContainerStatus': 0, 'error_message': 'Container does not exist'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
except:
|
||||||
|
data_ret = {'assignContainerStatus': 0, 'error_message': 'Unknown'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
con = Containers(admin=admin,
|
||||||
|
name=name,
|
||||||
|
cid=container.id)
|
||||||
|
|
||||||
|
con.save()
|
||||||
|
|
||||||
|
data_ret = {'assignContainerStatus': 1, 'error_message': 'None'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
data_ret = {'assignContainerStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def searchImage(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
string = data['string']
|
||||||
|
try:
|
||||||
|
matches = client.images.search(term=string)
|
||||||
|
except docker.errors.APIError as err:
|
||||||
|
data_ret = {'searchImageStatus': 0, 'error_message': str(err)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
except:
|
||||||
|
data_ret = {'searchImageStatus': 0, 'error_message': 'Unknown'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
print json.dumps(matches)
|
||||||
|
|
||||||
|
for image in matches:
|
||||||
|
if "/" in image['name']:
|
||||||
|
image['name2'] = image['name'].split("/")[0] + ":" + image['name'].split("/")[1]
|
||||||
|
else:
|
||||||
|
image['name2'] = image['name']
|
||||||
|
|
||||||
|
|
||||||
|
data_ret = {'searchImageStatus': 1, 'error_message': 'None', 'matches':matches}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
data_ret = {'searchImageStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def images(self, request = None, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
imageList = client.images.list()
|
||||||
|
except docker.errors.APIError as err:
|
||||||
|
return HttpResponse(str(err))
|
||||||
|
|
||||||
|
images = {}
|
||||||
|
names = []
|
||||||
|
|
||||||
|
for image in imageList:
|
||||||
|
name = image.attrs['RepoTags'][0].split(":")[0]
|
||||||
|
if "/" in name:
|
||||||
|
name2 = ""
|
||||||
|
for item in name.split("/"):
|
||||||
|
name2 += ":" + item
|
||||||
|
else:
|
||||||
|
name2 = name
|
||||||
|
|
||||||
|
tags = []
|
||||||
|
for tag in image.tags:
|
||||||
|
getTag = tag.split(":")
|
||||||
|
if len(getTag) == 2:
|
||||||
|
tags.append(getTag[1])
|
||||||
|
print tags
|
||||||
|
if name in names:
|
||||||
|
images[name]['tags'].extend(tags)
|
||||||
|
else:
|
||||||
|
names.append(name)
|
||||||
|
images[name] = {"name":name,
|
||||||
|
"name2":name2,
|
||||||
|
"tags":tags}
|
||||||
|
print "======"
|
||||||
|
print images
|
||||||
|
return render(request, 'dockerManager/images.html', {"images":images, "test":'asds'})
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
return HttpResponse(str(msg))
|
||||||
|
|
||||||
|
def manageImages(self, request = None, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
imageList = client.images.list()
|
||||||
|
|
||||||
|
images = {}
|
||||||
|
names = []
|
||||||
|
|
||||||
|
for image in imageList:
|
||||||
|
name = image.attrs['RepoTags'][0].split(":")[0]
|
||||||
|
if name in names:
|
||||||
|
images[name]['tags'].extend(image.tags)
|
||||||
|
else:
|
||||||
|
names.append(name)
|
||||||
|
tags = []
|
||||||
|
images[name] = {"name":name,
|
||||||
|
"tags":image.tags}
|
||||||
|
return render(request, 'dockerManager/manageImages.html', {"images":images})
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
return HttpResponse(str(msg))
|
||||||
|
|
||||||
|
def getImageHistory(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
|
||||||
|
name = data['name']
|
||||||
|
try:
|
||||||
|
image = client.images.get(name)
|
||||||
|
except docker.errors.APIError as err:
|
||||||
|
data_ret = {'imageHistoryStatus': 0, 'error_message': str(err)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
except:
|
||||||
|
data_ret = {'imageHistoryStatus': 0, 'error_message': 'Unknown'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
data_ret = {'imageHistoryStatus': 1, 'error_message': 'None', 'history':image.history()}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
data_ret = {'imageHistoryStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def removeImage(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
name = data['name']
|
||||||
|
try:
|
||||||
|
if name == 0:
|
||||||
|
action = client.images.prune()
|
||||||
|
else:
|
||||||
|
action = client.images.remove(name)
|
||||||
|
print action
|
||||||
|
except docker.errors.APIError as err:
|
||||||
|
data_ret = {'removeImageStatus': 0, 'error_message': str(err)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
except:
|
||||||
|
data_ret = {'removeImageStatus': 0, 'error_message': 'Unknown'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
data_ret = {'removeImageStatus': 1, 'error_message': 'None'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
data_ret = {'removeImageStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
# Internal function for recreating containers
|
||||||
|
|
||||||
|
def doRecreateContainer(self, userID, data, con):
|
||||||
|
try:
|
||||||
|
name = data['name']
|
||||||
|
unlisted = data['unlisted'] # Pass this as 1 if image is not known for container
|
||||||
|
image = data['image']
|
||||||
|
tag = data['tag']
|
||||||
|
env = data['env']
|
||||||
|
port = data['ports']
|
||||||
|
memory = data['memory']
|
||||||
|
|
||||||
|
if image == 'unknown':
|
||||||
|
return "Image name not known"
|
||||||
|
# Call container delete function
|
||||||
|
delStatus = self.submitContainerDeletion(userID, data, True)
|
||||||
|
if delStatus != 0:
|
||||||
|
return delStatus
|
||||||
|
|
||||||
|
print env
|
||||||
|
containerArgs = {'image':image+":"+tag,
|
||||||
|
'detach':True,
|
||||||
|
'name':name,
|
||||||
|
'ports':port,
|
||||||
|
'environment':env,
|
||||||
|
'publish_all_ports': True,
|
||||||
|
'mem_limit': memory * 1048576}
|
||||||
|
|
||||||
|
if con.startOnReboot == 1:
|
||||||
|
containerArgs['restart_policy'] = {"Name": "always"}
|
||||||
|
|
||||||
|
container = client.containers.create(**containerArgs)
|
||||||
|
con.cid = container.id
|
||||||
|
con.save()
|
||||||
|
|
||||||
|
return 0
|
||||||
|
except BaseException, msg:
|
||||||
|
return str(msg)
|
||||||
|
|
||||||
|
def saveContainerSettings(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
name = data['name']
|
||||||
|
if ACLManager.checkContainerOwnership(name, userID) != 1:
|
||||||
|
return ACLManager.loadErrorJson('saveSettingsStatus',0)
|
||||||
|
|
||||||
|
memory = data['memory']
|
||||||
|
startOnReboot = data['startOnReboot']
|
||||||
|
envList = data['envList']
|
||||||
|
|
||||||
|
if startOnReboot == True:
|
||||||
|
startOnReboot = 1
|
||||||
|
rPolicy = {"Name": "always"}
|
||||||
|
else:
|
||||||
|
startOnReboot = 0
|
||||||
|
rPolicy = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
container = client.containers.get(name)
|
||||||
|
except docker.errors.NotFound as err:
|
||||||
|
data_ret = {'saveSettingsStatus': 0, 'error_message': 'Container does not exist'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
except:
|
||||||
|
data_ret = {'saveSettingsStatus': 0, 'error_message': 'Unknown'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
try:
|
||||||
|
container.update(mem_limit=memory * 1048576,
|
||||||
|
restart_policy = rPolicy)
|
||||||
|
except docker.errors.APIError as err:
|
||||||
|
data_ret = {'saveSettingsStatus': 0, 'error_message': str(err)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
con = Containers.objects.get(name=name)
|
||||||
|
con.memory = memory
|
||||||
|
con.startOnReboot = startOnReboot
|
||||||
|
|
||||||
|
if 'envConfirmation' in data and data['envConfirmation']:
|
||||||
|
# Formatting envList for usage
|
||||||
|
envDict = {}
|
||||||
|
for key, value in envList.iteritems():
|
||||||
|
if (value['name'] != '') or (value['value'] != ''):
|
||||||
|
envDict[value['name']] = value['value']
|
||||||
|
|
||||||
|
print envDict
|
||||||
|
# Prepare data for recreate function
|
||||||
|
data = {
|
||||||
|
'name': name,
|
||||||
|
'unlisted': 0,
|
||||||
|
'image': con.image,
|
||||||
|
'tag': con.tag,
|
||||||
|
'env': envDict,
|
||||||
|
'ports': json.loads(con.ports), # No filter needed now as its ports are filtered when adding to database
|
||||||
|
'memory': con.memory
|
||||||
|
}
|
||||||
|
|
||||||
|
recreateStatus = self.doRecreateContainer(userID, data, con)
|
||||||
|
if recreateStatus != 0:
|
||||||
|
data_ret = {'saveSettingsStatus': 0, 'error_message': str(recreateStatus)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
con.env = json.dumps(envDict)
|
||||||
|
con.save()
|
||||||
|
|
||||||
|
data_ret = {'saveSettingsStatus': 1, 'error_message': 'None'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
data_ret = {'saveSettingsStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def recreateContainer(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
name = data['name']
|
||||||
|
if ACLManager.checkContainerOwnership(name, userID) != 1:
|
||||||
|
return ACLManager.loadErrorJson('saveSettingsStatus',0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
container = client.containers.get(name)
|
||||||
|
except docker.errors.NotFound as err:
|
||||||
|
data_ret = {'recreateContainerStatus': 0, 'error_message': 'Container does not exist'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
except:
|
||||||
|
data_ret = {'recreateContainerStatus': 0, 'error_message': 'Unknown'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
con = Containers.objects.get(name=name)
|
||||||
|
|
||||||
|
# Prepare data for recreate function
|
||||||
|
data = {
|
||||||
|
'name': name,
|
||||||
|
'unlisted': 0,
|
||||||
|
'image': con.image,
|
||||||
|
'tag': con.tag,
|
||||||
|
'env': json.loads(con.env),
|
||||||
|
'ports': json.loads(con.ports), # No filter needed now as its ports are filtered when adding to database
|
||||||
|
'memory': con.memory
|
||||||
|
}
|
||||||
|
|
||||||
|
recreateStatus = self.doRecreateContainer(userID, data, con)
|
||||||
|
if recreateStatus != 0:
|
||||||
|
data_ret = {'recreateContainerStatus': 0, 'error_message': str(recreateStatus)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
data_ret = {'recreateContainerStatus': 1, 'error_message': 'None'}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
data_ret = {'recreateContainerStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
def getTags(self, userID = None, data = None):
|
||||||
|
try:
|
||||||
|
image = data['image']
|
||||||
|
page = data['page']
|
||||||
|
|
||||||
|
if ":" in image:
|
||||||
|
image2 = image.split(":")[0] + "/" + image.split(":")[1]
|
||||||
|
else:
|
||||||
|
image2 = "library/" + image
|
||||||
|
|
||||||
|
print image
|
||||||
|
registryData = requests.get('https://registry.hub.docker.com/v2/repositories/'+image2+'/tags', {'page':page}).json()
|
||||||
|
|
||||||
|
tagList = []
|
||||||
|
for tag in registryData['results']:
|
||||||
|
tagList.append(tag['name'])
|
||||||
|
|
||||||
|
data_ret = {'getTagsStatus': 1, 'list': tagList, 'next':registryData['next'], 'error_message': None}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
|
except BaseException, msg:
|
||||||
|
data_ret = {'getTagsStatus': 0, 'error_message': str(msg)}
|
||||||
|
json_data = json.dumps(data_ret)
|
||||||
|
return HttpResponse(json_data)
|
||||||
94
websiteFunctions/migrations/0001_initial.py
Normal file
94
websiteFunctions/migrations/0001_initial.py
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2019-01-07 12:43
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('packages', '0001_initial'),
|
||||||
|
('loginSystem', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='aliasDomains',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('aliasDomain', models.CharField(max_length=75)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Backups',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('fileName', models.CharField(max_length=50)),
|
||||||
|
('date', models.CharField(max_length=50)),
|
||||||
|
('size', models.CharField(max_length=50)),
|
||||||
|
('status', models.IntegerField(default=0)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='backupSchedules',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('frequency', models.CharField(max_length=15)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ChildDomains',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('domain', models.CharField(max_length=50, unique=True)),
|
||||||
|
('path', models.CharField(default=None, max_length=200)),
|
||||||
|
('ssl', models.IntegerField()),
|
||||||
|
('phpSelection', models.CharField(default=None, max_length=10)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='dest',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('destLoc', models.CharField(max_length=18, unique=True)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Websites',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('domain', models.CharField(max_length=50, unique=True)),
|
||||||
|
('adminEmail', models.CharField(max_length=50)),
|
||||||
|
('phpSelection', models.CharField(max_length=10)),
|
||||||
|
('ssl', models.IntegerField()),
|
||||||
|
('state', models.IntegerField(default=1)),
|
||||||
|
('externalApp', models.CharField(default=None, max_length=10)),
|
||||||
|
('admin', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='loginSystem.Administrator')),
|
||||||
|
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='packages.Package')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='childdomains',
|
||||||
|
name='master',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='websiteFunctions.Websites'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='backupschedules',
|
||||||
|
name='dest',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='websiteFunctions.dest'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='backups',
|
||||||
|
name='website',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='websiteFunctions.Websites'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='aliasdomains',
|
||||||
|
name='master',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='websiteFunctions.Websites'),
|
||||||
|
),
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user