Commit ba97bf0e by x

Merge branch 'master' of ssh://giccero.cloud.ik.bme.hu/cloud

parents 360e818c 70397b80
...@@ -16,6 +16,10 @@ urlpatterns = patterns('', ...@@ -16,6 +16,10 @@ urlpatterns = patterns('',
url(r'^vm/new/(?P<template>\d+)/$', 'one.views.vm_new', name='vm_new'), url(r'^vm/new/(?P<template>\d+)/$', 'one.views.vm_new', name='vm_new'),
url(r'^vm/show/(?P<iid>\d+)/$', 'one.views.vm_show', name='vm_show'), url(r'^vm/show/(?P<iid>\d+)/$', 'one.views.vm_show', name='vm_show'),
url(r'^vm/delete/(?P<iid>\d+)/$', 'one.views.vm_delete', name='vm_delete'), url(r'^vm/delete/(?P<iid>\d+)/$', 'one.views.vm_delete', name='vm_delete'),
url(r'^vm/stop/(?P<iid>\d+)/$', 'one.views.vm_stop', name='vm_stop'),
url(r'^vm/resume/(?P<iid>\d+)/$', 'one.views.vm_resume', name='vm_resume'),
url(r'^vm/power_off/(?P<iid>\d+)/$', 'one.views.vm_power_off', name='vm_power_off'),
url(r'^vm/restart/(?P<iid>\d+)/$', 'one.views.vm_restart', name='vm_restart'),
url(r'^vm/port_add/(?P<iid>\d+)/$', 'one.views.vm_port_add', name='vm_port_add'), url(r'^vm/port_add/(?P<iid>\d+)/$', 'one.views.vm_port_add', name='vm_port_add'),
url(r'^vm/port_del/(?P<iid>\d+)/(?P<proto>tcp|udp)/(?P<public>\d+)/$', 'one.views.vm_port_del', name='vm_port_del'), url(r'^vm/port_del/(?P<iid>\d+)/(?P<proto>tcp|udp)/(?P<public>\d+)/$', 'one.views.vm_port_del', name='vm_port_del'),
url(r'^reload/$', 'firewall.views.reload_firewall', name='reload_firewall'), url(r'^reload/$', 'firewall.views.reload_firewall', name='reload_firewall'),
......
...@@ -6,16 +6,34 @@ from bottle import route, run, request, static_file, abort, redirect, app ...@@ -6,16 +6,34 @@ from bottle import route, run, request, static_file, abort, redirect, app
import json, os, shutil import json, os, shutil
import uuid import uuid
import subprocess import subprocess
import ConfigParser
from pwd import getpwnam from pwd import getpwnam
ROOT_WWW_FOLDER='/var/www' #Get configuration file
ROOT_BIN_FOLDER='/opt/store-server' config = ConfigParser.ConfigParser()
SITE_URL='http://store.cloud.ik.bme.hu:8080' config.read('store.config')
USER_MANAGER='UserManager.sh'
#ROOT_WWW_FOLDER='/var/www'
ROOT_WWW_FOLDER = config.get('store', 'root_www_folder')
#ROOT_BIN_FOLDER='/opt/store-server'
ROOT_BIN_FOLDER = config.get('store', 'root_bin_folder')
#SITE_URL='http://store.cloud.ik.bme.hu:8080'
SITE_URL = config.get('store', 'site_url')
#USER_MANAGER='UserManager.sh'
USER_MANAGER = config.get('store', 'user_manager')
#Standalone server
SITE_HOST = config.get('store', 'site_host')
SITE_PORT = config.get('store', 'site_port')
@route('/') @route('/')
def index(): def index():
return "It works!" response = "NONE"
try:
response = request.environi.get('SSL_CLIENT_VERIFY', 'NONE')
except:
pass
return "It works! SSL: "+response
#@route('/<neptun:re:[a-zA-Z0-9]{6}>', method='GET') #@route('/<neptun:re:[a-zA-Z0-9]{6}>', method='GET')
@route('/<neptun>', method='GET') @route('/<neptun>', method='GET')
...@@ -279,6 +297,6 @@ def getQuotaStatus(neptun): ...@@ -279,6 +297,6 @@ def getQuotaStatus(neptun):
return output.split() return output.split()
if __name__ == "__main__": if __name__ == "__main__":
run(host='0.0.0.0', port=8080) run(host=SITE_HOST, port=SITE_PORT)
else: else:
application=app() application=app()
#!/bin/bash
#
# Return values:
# 0: succesfully created
# 1: invalid syntax
# 2: user already exist
#
GRP_NAME="cloudusers"
COMMAND="$1"
USER_NAME="$2"
SMB_PASSWD="$3"
umask 022
case $COMMAND in
'add')
if [ "x${USER_NAME}" == "x" ]; then
exit 1
fi
if [ "x${SMB_PASSWD}" == "x" ]; then
exit 1
fi
#Check if user already exist
id ${USER_NAME} > /dev/null 2>&1
if [ $? == '0' ]; then
exit 2
fi
HOME_DIR="/home/${USER_NAME}/home"
mkdir -p ${HOME_DIR}
useradd --no-user-group --home ${HOME_DIR} --gid ${GRP_NAME} ${USER_NAME} >/dev/null 2>&1
adduser ${USER_NAME} ${GRP_NAME} >/dev/null 2>&1
chown ${USER_NAME}:cloudusers ${HOME_DIR} >/dev/null 2>&1
chmod 0755 ${HOME_DIR} >/dev/null 2>&1
chmod 0755 "/home/${USER_NAME}" 2>&1
#Set password to SMB_PASSWD
echo -e "${SMB_PASSWD}\n${SMB_PASSWD}\n" | passwd ${USER_NAME} >/dev/null 2>&1
#Set SMBPASSWD
# echo -e "${SMB_PASSWD}\n${SMB_PASSWD}" | (smbpasswd -a -s ${USER_NAME}) > /dev/null
echo "User ${USER_NAME} CREATED at `date`" >> /root/users.log
#Set quotas
# Username Soft Hard Inode Dev
# setquota ${USER_NAME} 2097152 2621440 0 0 /home
;;
'set')
id ${USER_NAME} > /dev/null 2>&1
if [ $? == '0' ]; then
echo -e "${SMB_PASSWD}\n${SMB_PASSWD}\n" | passwd ${USER_NAME} >/dev/null 2>&1
# echo -e "${SMB_PASSWD}\n${SMB_PASSWD}" | (smbpasswd -a -s ${USER_NAME}) > /dev/null
else
exit 2
fi
;;
'del')
id ${USER_NAME} > /dev/null 2>&1
if [ $? != '0' ]; then
exit 2
fi
# smbpasswd -x ${USER_NAME} >/dev/null 2>&1
deluser --remove-home ${USER_NAME} >/dev/null 2>&1
rmdir /home/${USER_NAME} >/dev/null 2>&1
echo "User ${USER_NAME} DELETED at `date`" >> /root/users.log
;;
'stat')
# stat=( $(quota -w ${USER_NAME} 2>/dev/null | tail -1 | awk '{ print $2" "$3" "$4 }') )
# USED_DISK=${stat[0]}
# SOFT_LIMIT=${stat[1]}
# HARD_LIMIT=${stat[3]}
case $3 in
'used')
echo $USED_DISK
;;
'soft')
echo $SOFT_LIMIT
;;
'hard')
echo $HARD_LIMIT
;;
esac
;;
'status')
# echo $(quota -w ${USER_NAME} 2>/dev/null | tail -1 | awk '{ print $2" "$3" "$4 }')
echo "1000 1000 1000"
;;
*)
echo "Usage: UserManager.sh COMMAND USER PASSWORD"
exit 1
;;
esac
...@@ -413,6 +413,40 @@ class Instance(models.Model): ...@@ -413,6 +413,40 @@ class Instance(models.Model):
self.firewall_host.delete() self.firewall_host.delete()
reload_firewall_lock() reload_firewall_lock()
"""
Change host state in OpenNebula.
"""
def _change_state(self, new_state):
from django.template.defaultfilters import escape
out = ""
with tempfile.NamedTemporaryFile(delete=False) as f:
os.chmod(f.name, stat.S_IRUSR|stat.S_IWUSR|stat.S_IRGRP|stat.S_IROTH)
tpl = u"""
<COMPUTE>
<ID>%(id)d</ID>
<STATE>%(state)s</STATE>
</COMPUTE>""" % {"id": self.one_id,
"state": new_state}
f.write(tpl)
f.close()
import subprocess
proc = subprocess.Popen(["/opt/occi.sh",
"compute", "update",
f.name], stdout=subprocess.PIPE)
(out, err) = proc.communicate()
os.unlink(f.name)
print "out: " + out
def stop(self):
self._change_state("STOPPED")
def resume(self):
self._change_state("RESUME")
def poweroff(self):
self._change_state("POWEROFF")
def restart(self):
self._change_state("RESTART")
class Meta: class Meta:
verbose_name = _('instance') verbose_name = _('instance')
verbose_name_plural = _('instances') verbose_name_plural = _('instances')
...@@ -23,6 +23,9 @@ a:link,a:visited{ ...@@ -23,6 +23,9 @@ a:link,a:visited{
margin:0; margin:0;
padding:5px; padding:5px;
} }
.contentblock ul{
list-style: none;
}
.contentblock h2 .contentblock h2
{ {
...@@ -107,14 +110,16 @@ a:link,a:visited{ ...@@ -107,14 +110,16 @@ a:link,a:visited{
.wm .details .value{ .wm .details .value{
float: right; float: right;
} }
.wm:hover{ .wm .summary:hover{
background-color: #b1b1b1; background-color: #b1b1b1;
} }
.wm .name{ .wm .name{
float: left; float: left;
} }
.wm .status{ .wm .status{
text-align: right;
float: right; float: right;
width: 60px;
} }
.wm .id{ .wm .id{
float: right; float: right;
...@@ -129,11 +134,15 @@ a:link,a:visited{ ...@@ -129,11 +134,15 @@ a:link,a:visited{
.file-list .info{ .file-list .info{
float: right; float: right;
width: 60px; width: 60px;
text-align: right;
} }
.wm .actions{ .wm .actions{
float: right; float: right;
width: 60px;
margin-left: 5px; margin-left: 5px;
display: none;
}
.wm:hover .actions{
display: block;
} }
.wm .actions a{ .wm .actions a{
height: 16px; height: 16px;
...@@ -154,9 +163,15 @@ a:link,a:visited{ ...@@ -154,9 +163,15 @@ a:link,a:visited{
.filetype-c { .filetype-c {
background-image: url(icons/document-visual-studio.png); background-image: url(icons/document-visual-studio.png);
} }
.filetype-text {
background-image: url(icons/document.png);
}
.filetype-image { .filetype-image {
background-image: url(icons/document-image.png); background-image: url(icons/document-image.png);
} }
.filetype-zip {
background-image: url(icons/folder-zipper.png);
}
.filetype-folder { .filetype-folder {
background-image: url(icons/folder-horizontal.png); background-image: url(icons/folder-horizontal.png);
} }
...@@ -260,6 +275,7 @@ body ...@@ -260,6 +275,7 @@ body
background-position:80px 0; background-position:80px 0;
margin:0; margin:0;
padding:0; padding:0;
overflow: scroll;
} }
#header #header
......
...@@ -11,23 +11,39 @@ ...@@ -11,23 +11,39 @@
<script src="/static/jquery.min.js"></script> <script src="/static/jquery.min.js"></script>
<script type="text/javascript"> <script type="text/javascript">
$(function(){ $(function(){
$('.wm').click(function(){ $('.wm .summary').click(function(){
if($(this).children('.details').is(':hidden')){ if($(this).next('.details').is(':hidden')){
$(this).children('.details') $(this).next('.details')
.css('height',0) .css('height',0)
.css('padding','0px 5px') .css('padding','0px 5px')
.show() .show()
.animate({height:160,paddingTop:15,paddingBottom:15},700); .animate({height:160,paddingTop:15,paddingBottom:15},700);
} else { } else {
var that=this; var that=this;
$(this).children('.details') $(this).next('.details')
.css('height',130) .css('height',130)
.css('padding','15px 5px') .css('padding','15px 5px')
.animate({height:0,paddingTop:0,paddingBottom:0},700,function(){ .animate({height:0,paddingTop:0,paddingBottom:0},700,function(){
$(that).children('.details').hide(); $(that).next('.details').hide();
}); });
} }
}) })
$('#load-more-files').click(function(){
$('.actions', this).show();
var that=this;
setTimeout(function(){
$(that).prev('li').slideDown(500,function(){
$('.actions', that).hide();
});
},2000);
})
$('#new-wm-button').click(function(){
$('#modal').show();
$('#modal-container').html($('#new-wm').html());
});
$('#shadow').click(function(){
$('#modal').hide();
})
}) })
</script> </script>
...@@ -77,5 +93,10 @@ $(function(){ ...@@ -77,5 +93,10 @@ $(function(){
<div id="content"> <div id="content">
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
<div id="modal" style="display: none">
<div id="shadow"></div>
<div id="modal-container">
</div>
</div>
</body> </body>
</html> </html>
<div class="contentblock" id="state">
<h2>Saját gépek</h2>
<div class="content">
{% if instances %} {% if instances %}
<table style="width:388px">
<!--<tr><th>#</th><th>Megnevezés</th><th>Állapot</th><th style="width: 96px">Műveletek</th></tr>-->
{% for i in instances %} {% for i in instances %}
<tr style="line-height: 22px;"> <li class="wm">
<td>{{i.id}}</td> <div class="summary">
<td><a href="/vm/show/{{i.id}}/" title="{{i.name}}">{{i.name|truncatechars:20}}</td> <!--<div class="id">161</div>-->
<td>{{i.state}}</td> <div class="name {% if i.state == 'ACTIVE' %}wm-on{% else %}wm-off{% endif %}">
<td> <a href="/vm/show/{{i.id}}/" title="{{i.name}}">{{i.name|truncatechars:20}}</a>
{% if i.state == 'ACTIVE' %} </div>
<a href="{{i.get_connect_uri}}" title="Csatlakozás"><img src="/static/icons/Video-display.png" alt="⌨" /></a><a href="/vm/suspend/{{i.id}}/" onclick="alert('Hamarosan a mozikban.'); return false" title="Felfüggesztés"><img src="/static/icons/Media-playback-pause.png" alt="||" /></a><a href="/vm/delete/{{i.id}}/" onclick="return confirm('Biztosan törli a gépet?')" title="Törlés"><img src="/static/icons/Edit-delete-2.png" alt="⌫" /></a><a href="/vm/reset/{{i.id}}/" onclick="alert('Hamarosan a mozikban.'); return false" title="Újraindítás"><img src="/static/icons/View-refresh.png" alt="↺" /></a> <div class="status">
{% endif %} {{i.state}}
{% if i.state == 'PENDING' %} </div>
<img src="/static/load-2.gif" /> indítás... <div class="actions">
{% endif %} {% if i.state == 'ACTIVE' %}
{% if i.state == 'SUSPENDED' %} <a href="{{i.get_connect_uri}}" title="Csatlakozás"><img src="static/icons/plug.png" alt="connect" /></a>
<a href="/vm/continue/{{i.id}}/" title="Folytatás"><img src="/static/icons/Media-playback-start.png" alt=">" /></a> <a href="/vm/suspend/{{i.id}}/" onclick="alert('Hamarosan a mozikban.'); return false" title="Felfüggesztés"><img src="/static/icons/control-pause.png" alt="pause" /></a>
<a href="/vm/delete/{{i.id}}/" onclick="return confirm('Biztosan törli a gépet?')" title="Törlés"><img src="/static/icons/Edit-delete-2.png" alt="⌫" /></a> <a href="/vm/delete/{{i.id}}/" onclick="return confirm('Biztosan törli a gépet?')" title="Törlés"><img src="/static/icons/minus-circle.png" alt="delete" /></a>
{% endif %} <a href="/vm/reset/{{i.id}}/" onclick="alert('Hamarosan a mozikban.'); return false" title="Újraindítás"><img src="/static/icons/arrow-circle-double.png" alt="↺" /></a>
{% if i.state == 'FAILED' %} {% endif %}
<a href="/vm/delete/{{i.id}}/" title="Törlés"><img src="/static/icons/Edit-delete-2.png" alt="⌫" /></a> {% if i.state == 'PENDING' %}
{% endif %} <img src="/static/load-2.gif" /> indítás...
{% endif %}
</td> {% if i.state == 'SUSPENDED' %}
</tr> <a href="/vm/continue/{{i.id}}/" title="Folytatás"><img src="/static/icons/control.png" alt="resume" /></a>
<a href="/vm/delete/{{i.id}}/" onclick="return confirm('Biztosan törli a gépet?')" title="Törlés"><img src="/static/icons/minus-circle.png" alt="delete" /></a>
{% endif %}
{% if i.state == 'FAILED' %}
<a href="/vm/delete/{{i.id}}/" title="Törlés"><img src="/static/icons/minus-circle.png" alt="delete" /></a>
{% endif %}
</div>
<div class="clear"></div>
</div>
<div class="details" style="display: none">
<h3>Részletek</h3>
<ul>
<li class="name">Gép neve: <span class="value">{{i.name}}</span></li>
<li class="os-linux">Operációs rendszer: <span class="value">{{i.template.disk.name}}</span></li>
<li class="type">Instance típus: <span class="value">{{i.template.instance_type.name}}</span></li>
<li class="date">Létrehozás dátuma: <span class="value">{{i.created_at}}</span></li>
</ul>
</div>
</li>
{% endfor %} {% endfor %}
</table>
{% else %} {% else %}
<p>Nem fut egy gép sem.</p> <div id="new-wm-tooltip">
{% endif %} <div id="new-wm-tooltip-container">
</div> <p>
Még nem indított egy gépet sem.
</p>
<p>
Válasszon sablont, és iziben használhatja a kiválasztott rendszert.
</p>
</div> </div>
</div>
{% endif %}
\ No newline at end of file
...@@ -4,16 +4,25 @@ ...@@ -4,16 +4,25 @@
{% block content %} {% block content %}
<div class="boxes"> <div class="boxes">
<div class="contentblock" id="state"> <div class="contentblock" id="state">
<h2>Új virtuális gép indítása</h2> <h2>Virtuális gépek</h2>
<div class="content"> <ul class="wm-list">
{% for m in templates %} {% include "box-vmlist.html" %}
<form method="POST" action="/vm/new/{{m.pk}}/">{% csrf_token %} <li id="new-wm-button" class="wm">
<p><input type="submit" value="{{m.name}}" class="button widebutton"/></p> <div class="summary">
</form> <div class="name">Új gép indítása</div>
{% endfor %} <div class="clear"></div>
</div> </div>
</li>
<li id="new-wm" style="display: none">
<h2>Rendelkezésre álló sablonok</h2>
{% for m in templates %}
<form method="POST" action="/vm/new/{{m.pk}}/">{% csrf_token %}
<p><input type="submit" value="{{m.name}}" class="button widebutton"/></p>
</form>
{% endfor %}
</li>
</ul>
</div> </div>
{% include "box-vmlist.html" %}
{% for box in boxes %} {% for box in boxes %}
{% if forloop.counter0|divisibleby:2 %} {% if forloop.counter0|divisibleby:2 %}
<div class="contentblock"> <div class="contentblock">
...@@ -26,8 +35,6 @@ ...@@ -26,8 +35,6 @@
{% endfor %} {% endfor %}
</div> </div>
<div class="boxes"> <div class="boxes">
<div class="contentblock"> <div class="contentblock">
<h2> <h2>
Adattár Adattár
...@@ -37,12 +44,12 @@ ...@@ -37,12 +44,12 @@
<li class="wm"> <li class="wm">
<div class="summary"> <div class="summary">
<div class="name filetype-c">hello.c</div> <div class="name filetype-c">hello.c</div>
<div class="info">1 Kb</div>
<div class="actions"> <div class="actions">
<a href="#"><img src="/static/icons/pencil.png" alt="rename" /></a> <a href="#"><img src="/static/icons/pencil.png" alt="rename" /></a>
<a href="#"><img src="/static/icons/minus-circle.png" alt="delete" /></a> <a href="#"><img src="/static/icons/minus-circle.png" alt="delete" /></a>
<a href="#"><img src="/static/icons/download-cloud.png" alt="download" /></a> <a href="#"><img src="/static/icons/download-cloud.png" alt="download" /></a>
</div> </div>
<div class="info">1 Kb</div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
<div class="details"> <div class="details">
...@@ -58,12 +65,12 @@ ...@@ -58,12 +65,12 @@
<li class="wm"> <li class="wm">
<div class="summary"> <div class="summary">
<div class="name filetype-image">suna.jpg</div> <div class="name filetype-image">suna.jpg</div>
<div class="info">1 Kb</div>
<div class="actions"> <div class="actions">
<a href="#"><img src="/static/icons/pencil.png" alt="rename" /></a> <a href="#"><img src="/static/icons/pencil.png" alt="rename" /></a>
<a href="#"><img src="/static/icons/minus-circle.png" alt="delete" /></a> <a href="#"><img src="/static/icons/minus-circle.png" alt="delete" /></a>
<a href="#"><img src="/static/icons/download-cloud.png" alt="download" /></a> <a href="#"><img src="/static/icons/download-cloud.png" alt="download" /></a>
</div> </div>
<div class="info">1 Kb</div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
<div class="details"> <div class="details">
...@@ -79,11 +86,11 @@ ...@@ -79,11 +86,11 @@
<li class="wm"> <li class="wm">
<div class="summary"> <div class="summary">
<div class="name filetype-folder">poresz</div> <div class="name filetype-folder">poresz</div>
<div class="info">katalógus</div>
<div class="actions"> <div class="actions">
<a href="#"><img src="/static/icons/pencil.png" alt="rename" /></a> <a href="#"><img src="/static/icons/pencil.png" alt="rename" /></a>
<a href="#"><img src="/static/icons/minus-circle.png" alt="delete" /></a> <a href="#"><img src="/static/icons/minus-circle.png" alt="delete" /></a>
</div> </div>
<div class="info">katalógus</div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
<div class="details"> <div class="details">
...@@ -96,9 +103,35 @@ ...@@ -96,9 +103,35 @@
</ul> </ul>
</div> </div>
</li> </li>
<li class="file-details wm"> <li class="wm" style="display: none">
<div class="summary">
<div class="name filetype-text">matlab_serial.txt</div>
<div class="info">358 Kb</div>
<div class="actions">
<a href="#"><img src="/static/icons/pencil.png" alt="rename" /></a>
<a href="#"><img src="/static/icons/minus-circle.png" alt="delete" /></a>
<a href="#"><img src="/static/icons/download-cloud.png" alt="download" /></a>
</div>
<div class="clear"></div>
</div>
<div class="details">
<h3>Részletek</h3>
<ul>
<li>Létrehozva: <span class="value">2012.12.29. 23:12</span></li>
<li>Módosítva: <span class="value">2012.12.29. 23:12</span></li>
<li>Hozzáférés: <span class="value">2012.12.29. 23:12</span></li>
<li>Típus: <span class="value">text/plain</span></li>
</ul>
</div>
</li>
<li class="file-details wm" id="load-more-files">
<div class="summary"> <div class="summary">
<div class="name filetype-more">Mutasd a régebbi fájlokat!</div> <div class="name filetype-more">
Mutasd a régebbi fájlokat!
</div>
<div class="actions" style="text-align: right; display: none">
<img src="/static/load-3.gif" alt="loading" />
</div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
</li> </li>
...@@ -111,6 +144,5 @@ ...@@ -111,6 +144,5 @@
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
...@@ -162,6 +162,45 @@ class VmDeleteView(View): ...@@ -162,6 +162,45 @@ class VmDeleteView(View):
vm_delete = login_required(VmDeleteView.as_view()) vm_delete = login_required(VmDeleteView.as_view())
@login_required
@require_POST
def vm_stop(request, iid, *args, **kwargs):
try:
get_object_or_404(Instance, id=iid, owner=request.user).stop()
messages.success(request, _('Virtual machine is successfully stopped.'))
except:
messages.error(request, _('Failed to stop virtual machine.'))
return redirect('/')
@login_required
@require_POST
def vm_resume(request, iid, *args, **kwargs):
try:
get_object_or_404(Instance, id=iid, owner=request.user).resume()
messages.success(request, _('Virtual machine is successfully resumed.'))
except:
messages.error(request, _('Failed to resume virtual machine.'))
return redirect('/')
@login_required
@require_POST
def vm_power_off(request, iid, *args, **kwargs):
try:
get_object_or_404(Instance, id=iid, owner=request.user).poweroff()
messages.success(request, _('Virtual machine is successfully powered off.'))
except:
messages.error(request, _('Failed to power off virtual machine.'))
return redirect('/')
@login_required
@require_POST
def vm_restart(request, iid, *args, **kwargs):
try:
get_object_or_404(Instance, id=iid, owner=request.user).restart()
messages.success(request, _('Virtual machine is successfully restarted.'))
except:
messages.error(request, _('Failed to restart virtual machine.'))
return redirect('/')
def vm_active(request, token): def vm_active(request, token):
id = signing.loads(token, salt='activate', max_age=300) id = signing.loads(token, salt='activate', max_age=300)
......
from django.contrib import admin
from store.models import *
class SettingAdmin(admin.ModelAdmin):
list_display = ('key', 'value')
admin.site.register(Setting, SettingAdmin)
from django.db import models
from django.http import Http404
import json, requests, time
from modeldict import ModelDict
from store.models import settings
# Create your models here.
#TODO Handle exceptions locally
class StoreApi:
# store_url = 'https://store.cloud.ik.bme.hu'
# store_url = 'http://store.cloud.ik.bme.hu:8080'
# store_client_cert = '/opt/webadmin/cloud/client.crt'
# store_client_key = ''/opt/webadmin/cloud/client.key
# store_user = 'admin'
# store_password = 'IQu8Eice'
# ssl_auth = True
# verify_ssl = False
@staticmethod
def post_request(url, payload):
headers = {'content-type': 'application/json'}
if settings['ssl_auth'] == 'True' and settings['basic_auth'] == 'True':
r = requests.post(url, data=payload, headers=headers, \
verify = settings['verify_ssl'], \
cert=(settings['store_client_cert'], settings['store_client_key']), \
auth=(settings['store_client_user'], settings['store_client_pass'])
)
elif settings['ssl_auth'] == 'True':
r = requests.post(url, data=payload, headers=headers, \
verify = settings['verify_ssl'], \
cert=(settings['store_client_cert'], settings['store_client_key']) \
)
elif settings['basic_auth'] == 'True':
r = requests.post(url, data=payload, headers=headers, \
verify = settings['verify_ssl'], \
auth=(settings['store_client_user'], settings['store_client_pass']) \
)
else:
r = requests.post(url, data=payload, headers=headers, \
verify = settings['verify_ssl'] \
)
return r
@staticmethod
def get_request(url):
headers = {'content-type': 'application/json'}
if settings['ssl_auth'] == 'True' and settings['basic_auth'] == 'True':
r = requests.get(url, headers=headers, \
verify = settings['verify_ssl'], \
cert=(settings['store_client_cert'], settings['store_client_key']), \
auth=(settings['store_client_user'], settings['store_client_pass'])
)
elif settings['ssl_auth'] == 'True':
r = requests.get(url, headers=headers, \
verify = settings['verify_ssl'], \
cert=(settings['store_client_cert'], settings['store_client_key']) \
)
elif settings['basic_auth'] == 'True':
r = requests.get(url, headers=headers, \
verify = settings['verify_ssl'], \
auth=(settings['store_client_user'], settings['store_client_pass']) \
)
else:
r = requests.get(url, headers=headers, \
verify = settings['verify_ssl'] \
)
return r
@staticmethod
def listfolder(neptun, path):
url = settings['store_url']+'/'+neptun
payload = json.dumps({ 'CMD' : 'LIST', 'PATH' : path })
r = StoreApi.post_request(url, payload)
if r.status_code == requests.codes.ok:
tupplelist = json.loads(r.content)
for item in tupplelist:
item['MTIME'] = time.ctime(item['MTIME'])
return tupplelist
else:
raise Http404
@staticmethod
def requestdownload(neptun, path):
url = settings['store_url']+'/'+neptun
payload = json.dumps({ 'CMD' : 'DOWNLOAD', 'PATH' : path })
r = StoreApi.post_request(url, payload)
response = json.loads(r.content)
return response['LINK']
@staticmethod
def requestupload(neptun, path):
url = settings['store_url']+'/'+neptun
payload = json.dumps({ 'CMD' : 'UPLOAD', 'PATH' : path })
headers = {'content-type': 'application/json'}
r = StoreApi.post_request(url, payload)
response = json.loads(r.content)
if r.status_code == requests.codes.ok:
return response['LINK']
else:
raise Http404
@staticmethod
def requestremove(neptun, path):
url = settings['store_url']+'/'+neptun
payload = json.dumps({ 'CMD' : 'REMOVE', 'PATH' : path })
headers = {'content-type': 'application/json'}
r = StoreApi.post_request(url, payload)
if r.status_code == requests.codes.ok:
return True
else:
return False
@staticmethod
def requestnewfolder(neptun, path):
url = settings['store_url']+'/'+neptun
payload = json.dumps({ 'CMD' : 'NEW_FOLDER', 'PATH' : path })
headers = {'content-type': 'application/json'}
r = StoreApi.post_request(url, payload)
if r.status_code == requests.codes.ok:
return True
else:
return False
@staticmethod
def userexist(neptun):
url = settings['store_url']+'/'+neptun
r = StoreApi.get_request(url)
if r.status_code == requests.codes.ok:
return True
else:
return False
@staticmethod
def createuser(neptun, password, key_list):
url = settings['store_url']+'/new/'+neptun
payload = json.dumps({ 'SMBPASSWD' : password, 'KEYS' : key_list })
r = StoreApi.post_request(url, payload)
if r.status_code == requests.codes.ok:
return True
else:
return False
@staticmethod
def updateauthorizationinfo(neptun, password, key_list):
url = settings['store_url']+'/set/'+neptun
payload = json.dumps({ 'SMBPASSWD' : password, 'KEYS' : key_list })
r = StoreApi.post_request(url, payload)
if r.status_code == requests.codes.ok:
return True
else:
return False
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'Setting'
db.create_table('store_setting', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('key', self.gf('django.db.models.fields.CharField')(max_length=32)),
('value', self.gf('django.db.models.fields.CharField')(max_length=200)),
))
db.send_create_signal('store', ['Setting'])
def backwards(self, orm):
# Deleting model 'Setting'
db.delete_table('store_setting')
models = {
'store.setting': {
'Meta': {'object_name': 'Setting'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'key': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
'value': ('django.db.models.fields.CharField', [], {'max_length': '200'})
}
}
complete_apps = ['store']
\ No newline at end of file
from django.db import models from django.db import models
from django.http import Http404 from modeldict import ModelDict
import json, requests, time
# Create your models here.
#TODO Handle exceptions locally
class StoreApi(models.Model):
# store_url = 'https://store.cloud.ik.bme.hu'
store_url = 'http://store.cloud.ik.bme.hu:8080'
store_user = 'admin'
store_password = 'IQu8Eice'
basic_auth = True
verify_ssl = False
@staticmethod
def listfolder(neptun, path):
url = StoreApi.store_url+'/'+neptun
payload = json.dumps({ 'CMD' : 'LIST', 'PATH' : path })
headers = {'content-type': 'application/json'}
if StoreApi.basic_auth:
r = requests.post(url, data=payload, headers=headers, auth=(StoreApi.store_user, StoreApi.store_password), verify=StoreApi.verify_ssl)
else:
r = requests.post(url, data=payload, headers=headers)
if r.status_code == requests.codes.ok:
tupplelist = json.loads(r.content)
for item in tupplelist:
item['MTIME'] = time.ctime(item['MTIME'])
return tupplelist
else:
raise Http404
@staticmethod
def requestdownload(neptun, path):
url = StoreApi.store_url+'/'+neptun
payload = json.dumps({ 'CMD' : 'DOWNLOAD', 'PATH' : path })
headers = {'content-type': 'application/json'}
if StoreApi.basic_auth:
r = requests.post(url, data=payload, headers=headers, auth=(StoreApi.store_user, StoreApi.store_password), verify=StoreApi.verify_ssl)
else:
r = requests.post(url, data=payload, headers=headers)
response = json.loads(r.content)
return response['LINK']
@staticmethod
def requestupload(neptun, path):
url = StoreApi.store_url+'/'+neptun
payload = json.dumps({ 'CMD' : 'UPLOAD', 'PATH' : path })
headers = {'content-type': 'application/json'}
if StoreApi.basic_auth:
r = requests.post(url, data=payload, headers=headers, auth=(StoreApi.store_user, StoreApi.store_password), verify=StoreApi.verify_ssl)
else:
r = requests.post(url, data=payload, headers=headers)
response = json.loads(r.content)
if r.status_code == requests.codes.ok:
return response['LINK']
else:
raise Http404
@staticmethod
def requestremove(neptun, path):
url = StoreApi.store_url+'/'+neptun
payload = json.dumps({ 'CMD' : 'REMOVE', 'PATH' : path })
headers = {'content-type': 'application/json'}
if StoreApi.basic_auth:
r = requests.post(url, data=payload, headers=headers, auth=(StoreApi.store_user, StoreApi.store_password), verify=StoreApi.verify_ssl)
else:
r = requests.post(url, data=payload, headers=headers)
if r.status_code == requests.codes.ok:
return True
else:
return False
@staticmethod
def requestnewfolder(neptun, path):
url = StoreApi.store_url+'/'+neptun
payload = json.dumps({ 'CMD' : 'NEW_FOLDER', 'PATH' : path })
headers = {'content-type': 'application/json'}
if StoreApi.basic_auth:
r = requests.post(url, data=payload, headers=headers, auth=(StoreApi.store_user, StoreApi.store_password), verify=StoreApi.verify_ssl)
else:
r = requests.post(url, data=payload, headers=headers)
if r.status_code == requests.codes.ok:
return True
else:
return False
@staticmethod
def userexist(neptun):
url = StoreApi.store_url+'/'+neptun
if StoreApi.basic_auth:
r = requests.get(url, auth=(StoreApi.store_user,StoreApi.store_password), verify=StoreApi.verify_ssl)
else:
r = requests.get(url)
if r.status_code == requests.codes.ok:
return True
else:
return False
@staticmethod
def createuser(neptun, password, key_list):
url = StoreApi.store_url+'/new/'+neptun
payload = json.dumps({ 'SMBPASSWD' : password, 'KEYS' : key_list })
headers = {'content-type': 'application/json'}
if StoreApi.basic_auth:
r = requests.post(url, data=payload, headers=headers, auth=(StoreApi.store_user, StoreApi.store_password), verify=StoreApi.verify_ssl)
else:
r = requests.post(url, data=payload, headers=headers)
if r.status_code == requests.codes.ok:
return True
else:
return False
@staticmethod
def updateauthorizationinfo(neptun, password, key_list):
url = StoreApi.store_url+'/set/'+neptun
payload = json.dumps({ 'SMBPASSWD' : password, 'KEYS' : key_list })
headers = {'content-type': 'application/json'}
if StoreApi.basic_auth:
r = requests.post(url, data=payload, headers=headers, auth=(StoreApi.store_user, StoreApi.store_password), verify=StoreApi.verify_ssl)
else:
r = requests.post(url, data=payload, headers=headers)
if r.status_code == requests.codes.ok:
return True
else:
return False
class Setting(models.Model):
key = models.CharField(max_length=32)
value = models.CharField(max_length=200)
settings = ModelDict(Setting, key='key', value='value', instances=False)
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
from django.http import HttpResponse from django.http import HttpResponse
from django.shortcuts import render_to_response, redirect from django.shortcuts import render_to_response, redirect
from django.template import RequestContext from django.template import RequestContext
from store.models import StoreApi from store.api import StoreApi
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User from django.contrib.auth.models import User
import os import os
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment