+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/dockerManager/templates/dockerManager/index.html b/dockerManager/templates/dockerManager/index.html
new file mode 100644
index 000000000..f108fc189
--- /dev/null
+++ b/dockerManager/templates/dockerManager/index.html
@@ -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 %}
+
+
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/dockerManager/templates/dockerManager/install.html b/dockerManager/templates/dockerManager/install.html
new file mode 100644
index 000000000..a3de1b5c9
--- /dev/null
+++ b/dockerManager/templates/dockerManager/install.html
@@ -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 %}
+
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/dockerManager/templates/dockerManager/listContainers.html b/dockerManager/templates/dockerManager/listContainers.html
new file mode 100644
index 000000000..b49a5de34
--- /dev/null
+++ b/dockerManager/templates/dockerManager/listContainers.html
@@ -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 %}
+
+
+
+
+
+
+
{% trans "List Containers" %}
+ Create
+
+
{% trans "Manage containers on server" %}
+
+
+
+
+
+ {% trans "Containers" %}
+
+
+
+
+
+
+ Name
+ Launch
+ Owner
+ Image
+ Tag
+ Actions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{% trans "Error message:" %} {$ errorMessage $}
+
+
+
+
+ {% if showUnlistedContainer %}
+
+ {% trans "Unlisted Containers" %}
+
+
+
+
+
+ Name
+ Status
+ Actions
+
+
+
+
+ {% for container in unlistedContainers %}
+
+ {{container.name}}
+ {{container.status}}
+
+
+
+
+
+
+ {% endfor %}
+
+
+
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/dockerManager/templates/dockerManager/manageImages.html b/dockerManager/templates/dockerManager/manageImages.html
new file mode 100644
index 000000000..4e219abdd
--- /dev/null
+++ b/dockerManager/templates/dockerManager/manageImages.html
@@ -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 %}
+
+
+
+
+
+
+
{% trans "Manage Images" %}
+ Create
+
+
{% trans "On this page you can manage docker images." %}
+
+
+
+
+
+
+
+
+
+
+
+
+ ID
+ CreatedBy
+ Created
+ Comment
+ Size
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% trans "Images" %}
+ {% trans "Images" %}
+ Prune
+
+
+
+
+
Search Image
+
+
+
+
+
+
+
+
+
+
+
+
+ Name (search)
+ Tags
+ Action
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% trans "Pull" %}
+
+
+
+
+
+
+
+
+
+ Name (Installed)
+ Tags
+ Action
+
+
+
+
+
+ {% for name, image in images.items %}
+
+
+ {{image.name}}
+
+
+ {% for tag in image.tags%}
+ {{tag}}
+ {% endfor %}
+
+
+
+
+
+
+
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/dockerManager/templates/dockerManager/runContainer.html b/dockerManager/templates/dockerManager/runContainer.html
new file mode 100644
index 000000000..f801432fd
--- /dev/null
+++ b/dockerManager/templates/dockerManager/runContainer.html
@@ -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 %}
+
+
+
+
+
{% trans "Run Container" %}
+
{% trans "Modify parameters for your new container" %}
+
+
+
+
+
+
+ {% trans "Container Details" %}
+
+
+
+
+
+
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/dockerManager/templates/dockerManager/viewContainer.html b/dockerManager/templates/dockerManager/viewContainer.html
new file mode 100644
index 000000000..3baa62e11
--- /dev/null
+++ b/dockerManager/templates/dockerManager/viewContainer.html
@@ -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 %}
+
+
+
+
+
+
+
{% trans "Manage Container" %}
+
{% trans "Currently managing: " %} {{ name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% trans "Memory Usage" %}
+
+
+
+
+
{{ memoryUsage | floatformat:"2" }}%
+
+
+
+
+
+ {% trans "CPU Usage" %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% trans "Container ID" %}: {{cid}}
+
+ {% trans "Image" %}: {{image}}
+
+
+
+
+ {% if ports %}
+ {% trans "Ports" %}:
+ {% for iport, eport in ports.items %}
+ {{iport}} {% trans "to" %} {{eport}}
+ {% endfor %}
+ {% endif %}
+
+
+
+
Settings
+
Recreate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Main Actions
+
+
+
Status:
+
+
+
Start
+
Restart
+
Stop
+
Remove
+
+
+
+
+
+
+
+
+
+
Other Actions
+
Restart on system reboot:
+
Export file
+
View Process
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {$ item $}
+
+
+
+
+
+ {$ item $}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/dockerManager/tests.py b/dockerManager/tests.py
new file mode 100644
index 000000000..5982e6bcd
--- /dev/null
+++ b/dockerManager/tests.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/dockerManager/urls.py b/dockerManager/urls.py
new file mode 100644
index 000000000..0bb5ca064
--- /dev/null
+++ b/dockerManager/urls.py
@@ -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
(.*))$', views.viewContainer, name='viewContainer'),
+]
\ No newline at end of file
diff --git a/dockerManager/views.py b/dockerManager/views.py
new file mode 100644
index 000000000..ce9b31bef
--- /dev/null
+++ b/dockerManager/views.py
@@ -0,0 +1,360 @@
+ # -*- 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
+
+# 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)
\ No newline at end of file
diff --git a/emailMarketing/migrations/0001_initial.py b/emailMarketing/migrations/0001_initial.py
new file mode 100644
index 000000000..9c0000b19
--- /dev/null
+++ b/emailMarketing/migrations/0001_initial.py
@@ -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'),
+ ),
+ ]
diff --git a/emailPremium/migrations/0001_initial.py b/emailPremium/migrations/0001_initial.py
new file mode 100644
index 000000000..343d614e1
--- /dev/null
+++ b/emailPremium/migrations/0001_initial.py
@@ -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')),
+ ],
+ ),
+ ]
diff --git a/firewall/migrations/0001_initial.py b/firewall/migrations/0001_initial.py
new file mode 100644
index 000000000..d3899c19d
--- /dev/null
+++ b/firewall/migrations/0001_initial.py
@@ -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)),
+ ],
+ ),
+ ]
diff --git a/ftp/migrations/0001_initial.py b/ftp/migrations/0001_initial.py
new file mode 100644
index 000000000..a611f1f23
--- /dev/null
+++ b/ftp/migrations/0001_initial.py
@@ -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',
+ },
+ ),
+ ]
diff --git a/loginSystem/migrations/0001_initial.py b/loginSystem/migrations/0001_initial.py
new file mode 100644
index 000000000..e03153842
--- /dev/null
+++ b/loginSystem/migrations/0001_initial.py
@@ -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')),
+ ],
+ ),
+ ]
diff --git a/mailServer/migrations/0001_initial.py b/mailServer/migrations/0001_initial.py
new file mode 100644
index 000000000..1fce24d41
--- /dev/null
+++ b/mailServer/migrations/0001_initial.py
@@ -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',
+ },
+ ),
+ ]
diff --git a/managePHP/migrations/0001_initial.py b/managePHP/migrations/0001_initial.py
new file mode 100644
index 000000000..c66f5ae7a
--- /dev/null
+++ b/managePHP/migrations/0001_initial.py
@@ -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'),
+ ),
+ ]
diff --git a/packages/migrations/0001_initial.py b/packages/migrations/0001_initial.py
new file mode 100644
index 000000000..a5eb96042
--- /dev/null
+++ b/packages/migrations/0001_initial.py
@@ -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')),
+ ],
+ ),
+ ]
diff --git a/plogical/acl.py b/plogical/acl.py
index 5902cf3b7..3ed15b444 100644
--- a/plogical/acl.py
+++ b/plogical/acl.py
@@ -8,6 +8,7 @@ from loginSystem.models import Administrator, ACL
from django.shortcuts import HttpResponse
from packages.models import Package
from websiteFunctions.models import Websites, ChildDomains
+from dockerManager.models import Containers
from dns.models import Domains
import json
from subprocess import call, CalledProcessError
@@ -363,6 +364,73 @@ class ACLManager:
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
+ 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
+ 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
def findWebsiteObjects(currentACL, userID):
@@ -456,4 +524,3 @@ class ACLManager:
-
diff --git a/plogical/container.py b/plogical/container.py
new file mode 100644
index 000000000..ff28c88f0
--- /dev/null
+++ b/plogical/container.py
@@ -0,0 +1,1042 @@
+#!/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
+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 = 'sudo yum install -y docker'
+ cmd = shlex.split(command)
+ res = subprocess.call(cmd)
+
+ command = 'sudo groupadd docker'
+ cmd = shlex.split(command)
+ res2 = subprocess.call(cmd)
+
+ command = 'sudo usermod -aG docker cyberpanel'
+ cmd = shlex.split(command)
+ res3 = subprocess.call(cmd)
+
+ command = 'sudo service docker start'
+ cmd = shlex.split(command)
+ res4 = subprocess.call(cmd)
+
+ if res == 0 and res2 == 0 and res3 == 0 and res4 ==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:
+ admin = Administrator.objects.get(pk=userID)
+ if admin.acl.adminStatus != 1:
+ return ACLManager.loadError()
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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]
+
+ 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()
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+ 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:
+ if ACLManager.checkContainerOwnership(name, userID) != 1:
+ return ACLManager.loadError()
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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(' ')
+ else:
+ pages = ceil(pages)
+ finalPages = int(pages) + 1
+
+ for i in range(1, finalPages):
+ pagination.append('' + str(i) + ' ')
+
+ 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)
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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:
+
+ admin = Administrator.objects.get(pk=userID)
+ if admin.acl.adminStatus != 1:
+ return ACLManager.loadErrorJson('createContainerStatus',0)
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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:
+
+ admin = Administrator.objects.get(pk=userID)
+ if admin.acl.adminStatus != 1:
+ return ACLManager.loadErrorJson('installImageStatus',0)
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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)
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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:
+ admin = Administrator.objects.get(pk=userID)
+ if admin.acl.adminStatus != 1:
+ return ACLManager.loadErrorJson('listContainerStatus',0)
+
+ 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):
+ admin = Administrator.objects.get(pk=userID)
+ if admin.acl.adminStatus != 1:
+ return ACLManager.loadError()
+
+ 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)
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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)
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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)
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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)
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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
+ admin = Administrator.objects.get(pk=userID)
+ if admin.acl.adminStatus != 1:
+ return ACLManager.loadErrorJson('assignContainerStatus',0)
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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:
+ admin = Administrator.objects.get(pk=userID)
+ if admin.acl.adminStatus != 1:
+ return ACLManager.loadErrorJson('searchImageStatus',0)
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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:
+ admin = Administrator.objects.get(pk=userID)
+ if admin.acl.adminStatus != 1:
+ return ACLManager.loadError()
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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:
+ admin = Administrator.objects.get(pk=userID)
+ if admin.acl.adminStatus != 1:
+ return ACLManager.loadError()
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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']
+
+ if ACLManager.checkContainerOwnership(name, userID) != 1:
+ return ACLManager.loadError()
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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:
+ admin = Administrator.objects.get(pk=userID)
+ if admin.acl.adminStatus != 1:
+ return ACLManager.loadError()
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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)
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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)
+
+ client = docker.from_env()
+ dockerAPI = docker.APIClient()
+
+ 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:
+
+ admin = Administrator.objects.get(pk=userID)
+ if admin.acl.adminStatus != 1:
+ return ACLManager.loadError()
+
+ 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)
\ No newline at end of file
diff --git a/static/dockerManager/dockerManager.js b/static/dockerManager/dockerManager.js
new file mode 100644
index 000000000..1faee184a
--- /dev/null
+++ b/static/dockerManager/dockerManager.js
@@ -0,0 +1,1106 @@
+app.controller('installDocker', function($scope,$http) {
+ $scope.installDockerStatus = true;
+ $scope.installDocker = function(){
+ $scope.installDockerStatus = false;
+ url = "/docker/installDocker";
+ var data = {};
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas);
+
+ function ListInitialDatas(response) {
+ if (response.data.installDockerStatus === 1)
+ {
+ new PNotify({
+ title: 'Docker installed',
+ text: 'Reloading...',
+ type: 'success'
+ });
+ location.reload();
+ }
+ else{
+ new PNotify({
+ title: 'Failed to complete request',
+ text: response.data.error,
+ type: 'error'
+ });
+ }
+ $scope.installDockerStatus = true;
+
+ }
+ function cantLoadInitialDatas(response) {
+ $scope.installDockerStatus = true;
+ new PNotify({
+ title: 'Failed to complete request',
+ type: 'error'
+ });
+ }
+ }
+});
+
+/* Java script code for docker management */
+var delayTimer = null;
+
+app.controller('dockerImages', function($scope,$http) {
+ $scope.tagList = [];
+ $scope.imageTag = {};
+});
+
+/* Java script code to install Container */
+
+app.controller('runContainer', function($scope,$http) {
+ $scope.containerCreationLoading = true;
+ $scope.installationDetailsForm = false;
+ $scope.installationProgress = true;
+ $scope.errorMessageBox = true;
+ $scope.success = true;
+ $scope.couldNotConnect = true;
+ $scope.goBackDisable = true;
+
+ $scope.addEnvField = function() {
+ var countEnv = Object.keys($scope.envList).length;
+ $scope.envList[countEnv+1] = {'name':'', 'value':''};
+ }
+
+ var statusFile;
+
+ $scope.createContainer = function(){
+
+ console.log($scope.iport);
+ console.log($scope.portType);
+
+ $scope.containerCreationLoading = true;
+ $scope.installationDetailsForm = true;
+ $scope.installationProgress = false;
+ $scope.errorMessageBox = true;
+ $scope.success = true;
+ $scope.couldNotConnect = true;
+ $scope.goBackDisable = true;
+
+ $scope.currentStatus = "Starting creation..";
+
+ url = "/docker/submitContainerCreation";
+
+ var name = $scope.name;
+ var tag = $scope.tag;
+ var memory = $scope.memory;
+ var dockerOwner = $scope.dockerOwner;
+ var image = $scope.image;
+ var numberOfEnv = Object.keys($scope.envList).length;
+
+ var data = {
+ name: name,
+ tag: tag,
+ memory: memory,
+ dockerOwner: dockerOwner,
+ image: image,
+ envList: $scope.envList
+
+ };
+
+ $.each($scope.portType, function( port, protocol ) {
+ data[port + "/" + protocol] = $scope.eport[port];
+ });
+
+ console.log(data)
+
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas);
+
+
+ function ListInitialDatas(response) {
+
+ if (response.data.createContainerStatus === 1)
+ {
+ $scope.currentStatus = "Successful. Redirecting...";
+ window.location.href = "/docker/view/" + $scope.name
+ }
+ else{
+
+ $scope.containerCreationLoading = true;
+ $scope.installationDetailsForm = true;
+ $scope.installationProgress = false;
+ $scope.errorMessageBox = false;
+ $scope.success = true;
+ $scope.couldNotConnect = true;
+ $scope.goBackDisable = false;
+
+ $scope.errorMessage = response.data.error_message;
+ }
+
+
+
+ }
+ function cantLoadInitialDatas(response) {
+
+ $scope.containerCreationLoading = true;
+ $scope.installationDetailsForm = true;
+ $scope.installationProgress = false;
+ $scope.errorMessageBox = true;
+ $scope.success = true;
+ $scope.couldNotConnect = false;
+ $scope.goBackDisable = false;
+
+ }
+ };
+ $scope.goBack = function () {
+ $scope.containerCreationLoading = true;
+ $scope.installationDetailsForm = false;
+ $scope.installationProgress = true;
+ $scope.errorMessageBox = true;
+ $scope.success = true;
+ $scope.couldNotConnect = true;
+ $scope.goBackDisable = true;
+ $("#installProgress").css("width", "0%");
+ };
+
+});
+
+/* Javascript code for listing containers */
+
+
+app.controller('listContainers', function($scope,$http) {
+ $scope.activeLog = "";
+ $scope.assignActive = "";
+
+ $scope.assignContainer = function(name){
+ $("#assign").modal("show");
+ $scope.assignActive = name;
+ }
+
+ $scope.submitAssignContainer = function(){
+ url = "/docker/assignContainer";
+
+ var data = {name: $scope.assignActive, admin: $scope.dockerOwner};
+
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+
+ function ListInitialData(response) {
+
+ if (response.data.assignContainerStatus === 1) {
+ new PNotify({
+ title: 'Container assigned successfully',
+ type: 'success'
+ });
+ window.location.href = '/docker/listContainers';
+ }
+ else
+ {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+ }
+ $("#assign").modal("hide");
+ }
+ function cantLoadInitialData(response) {
+ console.log("not good");
+ new PNotify({
+ title: 'Unable to complete request',
+ type: 'error'
+ });
+ $("#assign").modal("hide");
+ }
+ }
+
+ $scope.delContainer = function(name, unlisted=false){
+ (new PNotify({
+ title: 'Confirmation Needed',
+ text: 'Are you sure?',
+ icon: 'fa fa-question-circle',
+ hide: false,
+ confirm: {
+ confirm: true
+ },
+ buttons: {
+ closer: false,
+ sticker: false
+ },
+ history: {
+ history: false
+ }
+ })).get().on('pnotify.confirm', function() {
+ $('#imageLoading').show();
+ url = "/docker/delContainer";
+
+ var data = {name: name, unlisted: unlisted};
+
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+
+
+ function ListInitialData(response) {
+ console.log(response);
+
+ if (response.data.delContainerStatus === 1) {
+ location.reload();
+ }
+ else if (response.data.delContainerStatus == 2) {
+ (new PNotify({
+ title: response.data.error_message,
+ text: 'Delete anyway?',
+ icon: 'fa fa-question-circle',
+ hide: false,
+ confirm: {
+ confirm: true
+ },
+ buttons: {
+ closer: false,
+ sticker: false
+ },
+ history: {
+ history: false
+ }
+ })).get().on('pnotify.confirm', function() {
+ url = "/docker/delContainer";
+
+ var data = {name: name, unlisted: unlisted, force: 1};
+
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+
+
+ function ListInitialData(response) {
+ if (response.data.delContainerStatus === 1) {
+ location.reload();
+ }
+ else {
+ $("#listFail").fadeIn();
+ $scope.errorMessage = response.data.error_message;
+ }
+ $('#imageLoading').hide();
+ }
+ function cantLoadInitialData(response) {
+ $('#imageLoading').hide();
+ }
+ })
+ }
+ else
+ {
+ $("#listFail").fadeIn();
+ $scope.errorMessage = response.data.error_message;
+ }
+ $('#imageLoading').hide();
+ }
+ function cantLoadInitialData(response) {
+ $('#imageLoading').hide();
+ }
+ })
+ }
+
+ $scope.showLog = function(name, refresh = false){
+ $scope.logs = "";
+ if (refresh === false){
+ $('#logs').modal('show');
+ $scope.activeLog = name;
+ }
+ else {
+ name = $scope.activeLog;
+ }
+ console.log(name)
+ $scope.logs = "Loading...";
+
+ url = "/docker/getContainerLogs";
+
+ var data = {name: name};
+
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+
+
+ function ListInitialData(response) {
+ console.log(response);
+
+ if (response.data.containerLogStatus === 1) {
+ $scope.logs = response.data.containerLog;
+ }
+ else
+ {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+
+ }
+ }
+ function cantLoadInitialData(response) {
+ new PNotify({
+ title: 'Unable to complete request',
+ type: 'error'
+ });
+ }
+ }
+
+ url = "/docker/getContainerList";
+
+ var data = {page: 1};
+
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+
+
+ function ListInitialData(response) {
+ console.log(response);
+
+ if (response.data.listContainerStatus === 1) {
+
+ var finalData = JSON.parse(response.data.data);
+ $scope.ContainerList = finalData;
+ console.log($scope.ContainerList);
+ $("#listFail").hide();
+ }
+ else
+ {
+ $("#listFail").fadeIn();
+ $scope.errorMessage = response.data.error_message;
+
+ }
+ }
+ function cantLoadInitialData(response) {
+ console.log("not good");
+ }
+
+
+ $scope.getFurtherContainersFromDB = function(pageNumber) {
+
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ var data = {page: pageNumber};
+
+
+ dataurl = "/docker/getContainerList";
+
+ $http.post(dataurl, data,config).then(ListInitialData, cantLoadInitialData);
+
+
+ function ListInitialData(response) {
+ if (response.data.listContainerStatus ===1) {
+
+ var finalData = JSON.parse(response.data.data);
+ $scope.ContainerList = finalData;
+ $("#listFail").hide();
+ }
+ else
+ {
+ $("#listFail").fadeIn();
+ $scope.errorMessage = response.data.error_message;
+ console.log(response.data);
+
+ }
+ }
+ function cantLoadInitialData(response) {
+ console.log("not good");
+ }
+
+
+
+ };
+});
+
+/* Java script code for containerr home page */
+
+app.controller('viewContainer', function($scope,$http) {
+ $scope.cName = "";
+ $scope.status = "";
+ $scope.savingSettings = false;
+ $scope.loadingTop = false;
+
+ $scope.recreate = function() {
+ (new PNotify({
+ title: 'Confirmation Needed',
+ text: 'Are you sure?',
+ icon: 'fa fa-question-circle',
+ hide: false,
+ confirm: {
+ confirm: true
+ },
+ buttons: {
+ closer: false,
+ sticker: false
+ },
+ history: {
+ history: false
+ }
+ })).get().on('pnotify.confirm', function() {
+ $('#infoLoading').show();
+
+ url = "/docker/recreateContainer";
+ var data = {name: $scope.cName};
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+ function ListInitialData(response) {
+ if (response.data.recreateContainerStatus === 1) {
+ new PNotify({
+ title: 'Action completed!',
+ text: 'Redirecting...',
+ type: 'success'
+ });
+ location.reload();
+ }
+ else
+ {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+
+ }
+ $('#infoLoading').hide();
+ }
+ function cantLoadInitialData(response) {
+ PNotify.error({
+ title: 'Unable to complete request',
+ text: "Problem in connecting to server"
+ });
+ $('#actionLoading').hide();
+ }
+ })
+ }
+
+ $scope.addEnvField = function() {
+ var countEnv = Object.keys($scope.envList).length;
+ $scope.envList[countEnv+1] = {'name':'', 'value':''};
+ }
+
+ $scope.showTop = function(){
+ $scope.topHead = [];
+ $scope.topProcesses = [];
+ $scope.loadingTop = true;
+ $("#processes").modal("show");
+
+ url = "/docker/getContainerTop";
+ var data = {name: $scope.cName};
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+ function ListInitialData(response) {
+ if (response.data.containerTopStatus === 1) {
+ $scope.topHead = response.data.processes.Titles;
+ $scope.topProcesses = response.data.processes.Processes;
+ }
+ else
+ {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+
+ }
+ $scope.loadingTop = false;
+ }
+ function cantLoadInitialData(response) {
+ PNotify.error({
+ title: 'Unable to complete request',
+ text: "Problem in connecting to server"
+ });
+ $scope.loadingTop = false;
+ }
+
+ }
+
+ $scope.cRemove = function(){
+ (new PNotify({
+ title: 'Confirmation Needed',
+ text: 'Are you sure?',
+ icon: 'fa fa-question-circle',
+ hide: false,
+ confirm: {
+ confirm: true
+ },
+ buttons: {
+ closer: false,
+ sticker: false
+ },
+ history: {
+ history: false
+ }
+ })).get().on('pnotify.confirm', function() {
+ $('#actionLoading').show();
+
+ url = "/docker/delContainer";
+ var data = {name: $scope.cName, unlisted: false};
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+ function ListInitialData(response) {
+ if (response.data.delContainerStatus === 1) {
+ new PNotify({
+ title: 'Container deleted!',
+ text: 'Redirecting...',
+ type: 'success'
+ });
+ window.location.href = '/docker/listContainers';
+ }
+ else
+ {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+ }
+ $('#actionLoading').hide();
+ }
+ function cantLoadInitialData(response) {
+ PNotify.error({
+ title: 'Unable to complete request',
+ text: "Problem in connecting to server"
+ });
+ $('#actionLoading').hide();
+ }
+ })
+ }
+
+ $scope.refreshStatus = function(){
+ url = "/docker/getContainerStatus";
+ var data = {name: $scope.cName};
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+ function ListInitialData(response) {
+ if (response.data.containerStatus === 1) {
+ console.log(response.data.status);
+ $scope.status = response.data.status;
+ }
+ else
+ {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+
+ }
+ }
+ function cantLoadInitialData(response) {
+ PNotify.error({
+ title: 'Unable to complete request',
+ text: "Problem in connecting to server"
+ });
+ }
+
+ }
+
+ $scope.saveSettings = function(){
+ $('#containerSettingLoading').show();
+ url = "/docker/saveContainerSettings";
+ $scope.savingSettings = true;
+
+ var data = {
+ name: $scope.cName,
+ memory:$scope.memory,
+ startOnReboot: $scope.startOnReboot,
+ envConfirmation: $scope.envConfirmation,
+ envList: $scope.envList
+ };
+
+ console.log(data)
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+ function ListInitialData(response) {
+ if (response.data.saveSettingsStatus === 1) {
+ if ($scope.envConfirmation){
+ new PNotify({
+ title: 'Done. Redirecting...',
+ type: 'success'
+ });
+ location.reload();
+ }
+ else{
+ new PNotify({
+ title: 'Settings Saved',
+ type: 'success'
+ });
+ }
+ }
+ else
+ {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+
+ }
+ $('#containerSettingLoading').hide();
+ $scope.savingSettings = false;
+ }
+ function cantLoadInitialData(response) {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: "Problem in connecting to server",
+ type: 'error'
+ });
+ $('#containerSettingLoading').hide();
+ $scope.savingSettings = false;
+ }
+
+ if ($scope.startOnReboot === true){
+ $scope.rPolicy="Yes";
+ }
+ else{
+ $scope.rPolicy="No";
+ }
+
+ }
+
+ $scope.cAction = function(action){
+ $('#actionLoading').show();
+ console.log($scope.cName)
+ url = "/docker/doContainerAction";
+ var data = {name: $scope.cName, action: action};
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+
+
+ function ListInitialData(response) {
+ console.log(response);
+
+ if (response.data.containerActionStatus === 1) {
+ new PNotify({
+ title: 'Success!',
+ text: 'Action completed',
+ type: 'success'
+ });
+ $scope.status = response.data.status;
+ $scope.refreshStatus()
+ }
+ else
+ {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+
+ }
+ $('#actionLoading').hide();
+ }
+ function cantLoadInitialData(response) {
+ PNotify.error({
+ title: 'Unable to complete request',
+ text: "Problem in connecting to server"
+ });
+ $('#actionLoading').hide();
+ }
+
+ }
+
+ $scope.loadLogs = function(name){
+ $scope.logs = "Loading...";
+
+ url = "/docker/getContainerLogs";
+
+ var data = {name: name};
+
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+
+
+ function ListInitialData(response) {
+ console.log(response);
+
+ if (response.data.containerLogStatus === 1) {
+ $scope.logs = response.data.containerLog;
+ }
+ else
+ {
+ $scope.logs = response.data.error_message;
+
+ }
+ }
+ function cantLoadInitialData(response) {
+ console.log("not good");
+ $scope.logs = "Error loading log";
+ }
+ }
+
+});
+
+
+/* Java script code for docker image management */
+app.controller('manageImages', function($scope,$http) {
+ $scope.tagList = [];
+ $scope.showingSearch = false;
+ $("#searchResult").hide();
+
+ $scope.pullImage = function(image, tag){
+ function ListInitialDatas(response) {
+ if (response.data.installImageStatus === 1)
+ {
+ new PNotify({
+ title: 'Image pulled successfully',
+ text: 'Reloading...',
+ type: 'success'
+ });
+ location.reload()
+ }
+ else{
+ new PNotify({
+ title: 'Failed to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+ }
+
+ $('#imageLoading').hide();
+
+ }
+ function cantLoadInitialDatas(response) {
+ $('#imageLoading').hide();
+ new PNotify({
+ title: 'Failed to complete request',
+ type: 'error'
+ });
+ }
+ if (image && tag){
+ $('#imageLoading').show();
+
+ url = "/docker/installImage";
+ var data = {
+ image: image,
+ tag: tag
+ };
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas);
+
+ }
+ else {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: 'Please select a tag',
+ type: 'info'
+ });
+ }
+
+ }
+
+ $scope.searchImages = function(){
+ console.log($scope.searchString);
+ if (!$scope.searchString){
+ $("#searchResult").hide();
+ }
+ else {
+ $("#searchResult").show();
+ }
+ clearTimeout(delayTimer);
+ delayTimer = setTimeout(function() {
+ $('#imageLoading').show();
+
+ url = "/docker/searchImage";
+ var data = {
+ string: $scope.searchString
+ };
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas);
+
+ function ListInitialDatas(response) {
+ if (response.data.searchImageStatus === 1)
+ {
+ $scope.images = response.data.matches;
+ console.log($scope.images)
+ }
+ else{
+ new PNotify({
+ title: 'Failed to complete request',
+ text: response.data.error,
+ type: 'error'
+ });
+ }
+
+ $('#imageLoading').hide();
+
+ }
+ function cantLoadInitialDatas(response) {
+ $('#imageLoading').hide();
+ new PNotify({
+ title: 'Failed to complete request',
+ type: 'error'
+ });
+ }
+ }, 500);
+ }
+
+ function populateTagList(image, page){
+ $('imageLoading').show();
+ url = "/docker/getTags"
+ var data = {
+ image: image,
+ page: page+1
+ };
+
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+
+
+ function ListInitialData(response) {
+
+ if (response.data.getTagsStatus === 1) {
+ $scope.tagList[image].splice(-1,1);
+ $scope.tagList[image] = $scope.tagList[image].concat(response.data.list);
+
+ if (response.data.next != null){
+ $scope.tagList[image].push("Load more");
+ }
+ }
+ else
+ {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+ }
+ $('#imageLoading').hide();
+ }
+ function cantLoadInitialData(response) {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+ $('#imageLoading').hide();
+ }
+ }
+
+ $scope.runContainer = function(image){
+ $("#errorMessage").hide();
+ if ($scope.imageTag[image] !== undefined) {
+ $("#imageList").css("pointer-events","none");
+ }
+ else {
+ $("#errorMessage").show();
+ $scope.errorMessage = "Please select a tag";
+ }
+ }
+
+ $scope.loadTags = function(event){
+ var pagesloaded = $(event.target).data('pageloaded');
+ var image = event.target.id;
+
+ if (!pagesloaded) {
+ $scope.tagList[image] = ['Loading...'];
+ $(event.target).data('pageloaded',1);
+
+ populateTagList(image, pagesloaded);
+// $("#"+image+" option:selected").prop("selected", false);
+ }
+ }
+
+ $scope.selectTag = function(){
+ var image = event.target.id;
+ var selectedTag = $('#'+image).find(":selected").text();
+
+ if (selectedTag == 'Load more') {
+ var pagesloaded = $(event.target).data('pageloaded');
+ $(event.target).data('pageloaded', pagesloaded+1);
+
+ populateTagList(image, pagesloaded);
+ }
+ }
+
+ $scope.getHistory = function(counter){
+ $('#imageLoading').show();
+ var name = $("#"+counter).val()
+
+ url = "/docker/getImageHistory";
+
+ var data = {name: name};
+
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+
+
+ function ListInitialData(response) {
+ console.log(response);
+
+ if (response.data.imageHistoryStatus === 1) {
+ $('#history').modal('show');
+ $scope.historyList = response.data.history;
+ }
+ else
+ {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+ }
+ $('#imageLoading').hide();
+ }
+ function cantLoadInitialData(response) {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+ $('#imageLoading').hide();
+ }
+ }
+
+ $scope.rmImage = function(counter){
+
+ (new PNotify({
+ title: 'Confirmation Needed',
+ text: 'Are you sure?',
+ icon: 'fa fa-question-circle',
+ hide: false,
+ confirm: {
+ confirm: true
+ },
+ buttons: {
+ closer: false,
+ sticker: false
+ },
+ history: {
+ history: false
+ }
+ })).get().on('pnotify.confirm', function() {
+ $('#imageLoading').show();
+
+ if (counter == '0') {
+ var name = 0;
+ }
+ else {
+ var name = $("#"+counter).val()
+ }
+
+ url = "/docker/removeImage";
+
+ var data = {name: name};
+
+ var config = {
+ headers : {
+ 'X-CSRFToken': getCookie('csrftoken')
+ }
+ };
+
+ $http.post(url, data,config).then(ListInitialData, cantLoadInitialData);
+
+
+ function ListInitialData(response) {
+ console.log(response);
+
+ if (response.data.removeImageStatus === 1) {
+ new PNotify({
+ title: 'Image(s) removed',
+ type: 'success'
+ });
+ window.location.href = "/docker/manageImages";
+ }
+ else
+ {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+ }
+ $('#imageLoading').hide();
+ }
+ function cantLoadInitialData(response) {
+ new PNotify({
+ title: 'Unable to complete request',
+ text: response.data.error_message,
+ type: 'error'
+ });
+ $('#imageLoading').hide();
+ }
+
+ })
+ }
+});
\ No newline at end of file
diff --git a/websiteFunctions/migrations/0001_initial.py b/websiteFunctions/migrations/0001_initial.py
new file mode 100644
index 000000000..69a2f29fa
--- /dev/null
+++ b/websiteFunctions/migrations/0001_initial.py
@@ -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'),
+ ),
+ ]