mirror of
https://github.com/retspen/webvirtcloud
synced 2026-03-23 11:04:49 +00:00
Merge 748c167def into aa2a996e3f
This commit is contained in:
commit
72d57ebc21
10 changed files with 245 additions and 33 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import re
|
||||
import json
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from computes.models import Compute
|
||||
|
|
@ -13,6 +14,8 @@ class ComputeAddTcpForm(forms.Form):
|
|||
max_length=100)
|
||||
password = forms.CharField(error_messages={'required': _('No password has been entered')},
|
||||
max_length=100)
|
||||
gstfsd_key = forms.CharField(max_length=256, required=False)
|
||||
|
||||
|
||||
def clean_name(self):
|
||||
name = self.cleaned_data['name']
|
||||
|
|
@ -41,6 +44,20 @@ class ComputeAddTcpForm(forms.Form):
|
|||
return hostname
|
||||
raise forms.ValidationError(_('This host is already connected'))
|
||||
|
||||
def clean_gstfsd_key(self):
|
||||
gstfsd_key = self.cleaned_data['gstfsd_key']
|
||||
try:
|
||||
data = json.loads(gstfsd_key)
|
||||
if not isinstance(data, dict):
|
||||
raise forms.ValidationError(_('Gstfsd key must be a json object'))
|
||||
if not 'k' in data:
|
||||
raise forms.ValidationError(_('Gstfsd key must have a "k" field'))
|
||||
if not 'kty' in data:
|
||||
raise forms.ValidationError(_('Gstfsd key must have a "kty" field'))
|
||||
except ValueError:
|
||||
raise forms.ValidationError(_('Gstfsd key must be a valid json'))
|
||||
return gstfsd_key
|
||||
|
||||
|
||||
class ComputeAddSshForm(forms.Form):
|
||||
name = forms.CharField(error_messages={'required': _('No hostname has been entered')},
|
||||
|
|
@ -49,6 +66,8 @@ class ComputeAddSshForm(forms.Form):
|
|||
max_length=100)
|
||||
login = forms.CharField(error_messages={'required': _('No login has been entered')},
|
||||
max_length=20)
|
||||
gstfsd_key = forms.CharField(max_length=256, required=False)
|
||||
|
||||
|
||||
def clean_name(self):
|
||||
name = self.cleaned_data['name']
|
||||
|
|
@ -77,6 +96,20 @@ class ComputeAddSshForm(forms.Form):
|
|||
return hostname
|
||||
raise forms.ValidationError(_('This host is already connected'))
|
||||
|
||||
def clean_gstfsd_key(self):
|
||||
gstfsd_key = self.cleaned_data['gstfsd_key']
|
||||
try:
|
||||
data = json.loads(gstfsd_key)
|
||||
if not isinstance(data, dict):
|
||||
raise forms.ValidationError(_('Gstfsd key must be a json object'))
|
||||
if not 'k' in data:
|
||||
raise forms.ValidationError(_('Gstfsd key must have a "k" field'))
|
||||
if not 'kty' in data:
|
||||
raise forms.ValidationError(_('Gstfsd key must have a "kty" field'))
|
||||
except ValueError:
|
||||
raise forms.ValidationError(_('Gstfsd key must be a valid json'))
|
||||
return gstfsd_key
|
||||
|
||||
|
||||
class ComputeAddTlsForm(forms.Form):
|
||||
name = forms.CharField(error_messages={'required': _('No hostname has been entered')},
|
||||
|
|
@ -87,6 +120,8 @@ class ComputeAddTlsForm(forms.Form):
|
|||
max_length=100)
|
||||
password = forms.CharField(error_messages={'required': _('No password has been entered')},
|
||||
max_length=100)
|
||||
gstfsd_key = forms.CharField(max_length=256, required=False)
|
||||
|
||||
|
||||
def clean_name(self):
|
||||
name = self.cleaned_data['name']
|
||||
|
|
@ -115,6 +150,20 @@ class ComputeAddTlsForm(forms.Form):
|
|||
return hostname
|
||||
raise forms.ValidationError(_('This host is already connected'))
|
||||
|
||||
def clean_gstfsd_key(self):
|
||||
gstfsd_key = self.cleaned_data['gstfsd_key']
|
||||
try:
|
||||
data = json.loads(gstfsd_key)
|
||||
if not isinstance(data, dict):
|
||||
raise forms.ValidationError(_('Gstfsd key must be a json object'))
|
||||
if not 'k' in data:
|
||||
raise forms.ValidationError(_('Gstfsd key must have a "k" field'))
|
||||
if not 'kty' in data:
|
||||
raise forms.ValidationError(_('Gstfsd key must have a "kty" field'))
|
||||
except ValueError:
|
||||
raise forms.ValidationError(_('Gstfsd key must be a valid json'))
|
||||
return gstfsd_key
|
||||
|
||||
|
||||
class ComputeEditHostForm(forms.Form):
|
||||
host_id = forms.CharField()
|
||||
|
|
@ -126,6 +175,8 @@ class ComputeEditHostForm(forms.Form):
|
|||
max_length=100)
|
||||
password = forms.CharField(max_length=100)
|
||||
|
||||
gstfsd_key = forms.CharField(max_length=256, required=False)
|
||||
|
||||
def clean_name(self):
|
||||
name = self.cleaned_data['name']
|
||||
have_symbol = re.match('[^a-zA-Z0-9._-]+', name)
|
||||
|
|
@ -145,11 +196,28 @@ class ComputeEditHostForm(forms.Form):
|
|||
raise forms.ValidationError(_('Wrong IP address'))
|
||||
return hostname
|
||||
|
||||
def clean_gstfsd_key(self):
|
||||
gstfsd_key = self.cleaned_data['gstfsd_key']
|
||||
try:
|
||||
data = json.loads(gstfsd_key)
|
||||
if not isinstance(data, dict):
|
||||
raise forms.ValidationError(_('Gstfsd key must be a json object'))
|
||||
if not 'k' in data:
|
||||
raise forms.ValidationError(_('Gstfsd key must have a "k" field'))
|
||||
if not 'kty' in data:
|
||||
raise forms.ValidationError(_('Gstfsd key must have a "kty" field'))
|
||||
except ValueError:
|
||||
raise forms.ValidationError(_('Gstfsd key must be a valid json'))
|
||||
return gstfsd_key
|
||||
|
||||
|
||||
class ComputeAddSocketForm(forms.Form):
|
||||
name = forms.CharField(error_messages={'required': _('No hostname has been entered')},
|
||||
max_length=20)
|
||||
|
||||
gstfsd_key = forms.CharField(max_length=256, required=False)
|
||||
|
||||
|
||||
def clean_name(self):
|
||||
name = self.cleaned_data['name']
|
||||
have_symbol = re.match('[^a-zA-Z0-9._-]+', name)
|
||||
|
|
@ -162,3 +230,17 @@ class ComputeAddSocketForm(forms.Form):
|
|||
except Compute.DoesNotExist:
|
||||
return name
|
||||
raise forms.ValidationError(_('This host is already connected'))
|
||||
|
||||
def clean_gstfsd_key(self):
|
||||
gstfsd_key = self.cleaned_data['gstfsd_key']
|
||||
try:
|
||||
data = json.loads(gstfsd_key)
|
||||
if not isinstance(data, dict):
|
||||
raise forms.ValidationError(_('Gstfsd key must be a json object'))
|
||||
if not 'k' in data:
|
||||
raise forms.ValidationError(_('Gstfsd key must have a "k" field'))
|
||||
if not 'kty' in data:
|
||||
raise forms.ValidationError(_('Gstfsd key must have a "kty" field'))
|
||||
except ValueError:
|
||||
raise forms.ValidationError(_('Gstfsd key must be a valid json'))
|
||||
return gstfsd_key
|
||||
|
|
|
|||
19
computes/migrations/0002_compute_gstfsd_key.py
Normal file
19
computes/migrations/0002_compute_gstfsd_key.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('computes', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='compute',
|
||||
name='gstfsd_key',
|
||||
field=models.CharField(max_length=256, null=True, blank=True),
|
||||
),
|
||||
]
|
||||
|
|
@ -7,6 +7,7 @@ class Compute(models.Model):
|
|||
login = models.CharField(max_length=20)
|
||||
password = models.CharField(max_length=14, blank=True, null=True)
|
||||
type = models.IntegerField()
|
||||
gstfsd_key = models.CharField(max_length=256, blank=True, null=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.hostname
|
||||
|
|
|
|||
|
|
@ -84,6 +84,12 @@
|
|||
<input type="password" name="password" class="form-control" value="{{ compute.password }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label">{% trans "Gstfsd key" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" name="gstfsd_key" class="form-control" value="{{ compute.gstfsd_key }}" maxlength="256">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="pull-left btn btn-danger" name="host_del">
|
||||
|
|
@ -121,6 +127,12 @@
|
|||
<input type="text" name="login" class="form-control" value="{{ compute.login }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label">{% trans "Gstfsd key" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" name="gstfsd_key" class="form-control" value="{{ compute.gstfsd_key }}" maxlength="256">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="pull-left btn btn-danger" name="host_del">
|
||||
|
|
@ -163,6 +175,12 @@
|
|||
<input type="password" name="password" class="form-control" value="{{ compute.password }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label">{% trans "Gstfsd key" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" name="gstfsd_key" class="form-control" value="{{ compute.gstfsd_key }}" maxlength="256">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="pull-left btn btn-danger" name="host_del">
|
||||
|
|
@ -187,6 +205,12 @@
|
|||
<input type="text" name="name" class="form-control" value="{{ compute.name }}" maxlength="20" required pattern="[a-z0-9\.\-_]+">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label">{% trans "Gstfsd key" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" name="gstfsd_key" class="form-control" value="{{ compute.gstfsd_key }}" maxlength="256">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="pull-left btn btn-danger" name="host_del">
|
||||
|
|
|
|||
|
|
@ -50,6 +50,12 @@
|
|||
<input type="password" name="password" class="form-control" placeholder="{% trans "Password" %}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label">{% trans "Gstfsd key" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" name="gstfsd_key" placeholder="Gstfsd JSON Web Key" class="form-control" value="{{ compute.gstfsd_key }}" maxlength="256">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">
|
||||
|
|
@ -83,6 +89,12 @@
|
|||
<input type="text" name="login" class="form-control" placeholder="{% trans "Username" %}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label">{% trans "Gstfsd key" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" name="gstfsd_key" placeholder="Gstfsd JSON Web Key" class="form-control" value="{{ compute.gstfsd_key }}" maxlength="256">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">
|
||||
|
|
@ -121,6 +133,12 @@
|
|||
<input type="password" name="password" class="form-control" placeholder="{% trans "Password" %}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label">{% trans "Gstfsd key" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" name="gstfsd_key" placeholder="Gstfsd JSON Web Key" class="form-control" value="{{ compute.gstfsd_key }}" maxlength="256">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">
|
||||
|
|
@ -141,6 +159,12 @@
|
|||
<input type="text" name="name" class="form-control" placeholder="Label Name" maxlength="20" required pattern="[a-z0-9\.\-_]+">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label">{% trans "Gstfsd key" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" name="gstfsd_key" placeholder="Gstfsd JSON Web Key" class="form-control" value="{{ compute.gstfsd_key }}" maxlength="256">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ def computes(request):
|
|||
'status': connection_manager.host_is_up(compute.type, compute.hostname),
|
||||
'type': compute.type,
|
||||
'login': compute.login,
|
||||
'password': compute.password
|
||||
'password': compute.password,
|
||||
'gstfsd_key': compute.gstfsd_key
|
||||
})
|
||||
return compute_data
|
||||
|
||||
|
|
@ -66,7 +67,8 @@ def computes(request):
|
|||
hostname=data['hostname'],
|
||||
type=CONN_TCP,
|
||||
login=data['login'],
|
||||
password=data['password'])
|
||||
password=data['password'],
|
||||
gstfsd_key=data['gstfsd_key'])
|
||||
new_tcp_host.save()
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
else:
|
||||
|
|
@ -79,7 +81,8 @@ def computes(request):
|
|||
new_ssh_host = Compute(name=data['name'],
|
||||
hostname=data['hostname'],
|
||||
type=CONN_SSH,
|
||||
login=data['login'])
|
||||
login=data['login'],
|
||||
gstfsd_key=data['gstfsd_key'])
|
||||
new_ssh_host.save()
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
else:
|
||||
|
|
@ -93,7 +96,8 @@ def computes(request):
|
|||
hostname=data['hostname'],
|
||||
type=CONN_TLS,
|
||||
login=data['login'],
|
||||
password=data['password'])
|
||||
password=data['password'],
|
||||
gstfsd_key=data['gstfsd_key'])
|
||||
new_tls_host.save()
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
else:
|
||||
|
|
@ -107,7 +111,8 @@ def computes(request):
|
|||
hostname='localhost',
|
||||
type=CONN_SOCKET,
|
||||
login='',
|
||||
password='')
|
||||
password='',
|
||||
gstfsd_key=data['gstfsd_key'])
|
||||
new_socket_host.save()
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
else:
|
||||
|
|
@ -122,6 +127,7 @@ def computes(request):
|
|||
compute_edit.hostname = data['hostname']
|
||||
compute_edit.login = data['login']
|
||||
compute_edit.password = data['password']
|
||||
compute_edit.gstfsd_key = data['gstfsd_key']
|
||||
compute_edit.save()
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@ import SocketServer
|
|||
import json
|
||||
import guestfs
|
||||
import re
|
||||
|
||||
import os
|
||||
from jwcrypto import jws, jwk, jwe
|
||||
|
||||
PORT = 16510
|
||||
ADDRESS = "0.0.0.0"
|
||||
SECRET = None
|
||||
|
||||
|
||||
class MyTCPServer(SocketServer.ThreadingTCPServer):
|
||||
|
|
@ -19,12 +21,20 @@ class MyTCPServer(SocketServer.ThreadingTCPServer):
|
|||
|
||||
class MyTCPServerHandler(SocketServer.BaseRequestHandler):
|
||||
def handle(self):
|
||||
# recive data
|
||||
data = json.loads(self.request.recv(1024).strip())
|
||||
|
||||
# GuestFS
|
||||
gfs = guestfs.GuestFS(python_return_dict=True)
|
||||
# recive data and check authentcation
|
||||
try:
|
||||
signed_data = jws.JWS()
|
||||
signed_data.deserialize(self.request.recv(4096).strip())
|
||||
signed_data.verify(SECRET, "HS512")
|
||||
|
||||
encrypted_data = jwe.JWE(algs=["A256KW", "A256CBC-HS512"])
|
||||
encrypted_data.deserialize(signed_data.payload)
|
||||
encrypted_data.decrypt(SECRET)
|
||||
|
||||
data = json.loads(encrypted_data.plaintext)
|
||||
|
||||
# GuestFS
|
||||
gfs = guestfs.GuestFS(python_return_dict=True)
|
||||
gfs.add_domain(data['vname'])
|
||||
gfs.launch()
|
||||
parts = gfs.list_partitions()
|
||||
|
|
@ -51,8 +61,29 @@ class MyTCPServerHandler(SocketServer.BaseRequestHandler):
|
|||
pass
|
||||
gfs.shutdown()
|
||||
gfs.close()
|
||||
except RuntimeError, err:
|
||||
# we check signature before trying to decrypt so jwe.InvalidJWEData should not be raised ever
|
||||
except (jws.InvalidJWSObject, jwe.InvalidJWEData, RuntimeError, ValueError) as err:
|
||||
self.request.sendall(json.dumps({'return': 'error', 'message': err.message}))
|
||||
|
||||
except jws.InvalidJWSSignature as err:
|
||||
self.request.sendall(json.dumps({'return': 'error', 'message': (
|
||||
"Fail to verify request signature. Check if you have imported "
|
||||
"the key (/var/lib/gstfsd/SECRET) in WebVirtCloud"
|
||||
)}))
|
||||
|
||||
if not os.path.isfile("/var/lib/gstfsd/SECRET"):
|
||||
try:
|
||||
os.mkdir("/var/lib/gstfsd")
|
||||
except OSError as error:
|
||||
if error.errno != 17: # File exists
|
||||
raise
|
||||
os.chmod("/var/lib/gstfsd", 0700)
|
||||
with open("/var/lib/gstfsd/SECRET", 'w') as f:
|
||||
f.write(jwk.JWK(generate='oct', size=256).export())
|
||||
os.chmod("/var/lib/gstfsd/SECRET", 0600)
|
||||
|
||||
with open("/var/lib/gstfsd/SECRET") as f:
|
||||
SECRET = jwk.JWK(**json.load(f))
|
||||
|
||||
server = MyTCPServer((ADDRESS, PORT), MyTCPServerHandler)
|
||||
server.serve_forever()
|
||||
|
|
|
|||
|
|
@ -2,5 +2,6 @@ Django==1.8.11
|
|||
websockify==0.8.0
|
||||
gunicorn==19.3.0
|
||||
libvirt-python==1.3.2
|
||||
jwcrypto>=0.2.1
|
||||
#http://github.com/retspen/retspen.github.io/raw/master/libxml2-python-2.9.1.tar.gz
|
||||
http://git.gnome.org/browse/libxml2/snapshot/libxml2-2.9.1.tar.gz#egg=libxml2-python&subdirectory=python
|
||||
|
|
|
|||
|
|
@ -245,10 +245,10 @@
|
|||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="rootpasswd">
|
||||
<p>{% trans "You need shut down your instance and enter a new root password." %}</p>
|
||||
<form class="form-inline" method="post" role="form">{% csrf_token %}
|
||||
<form class="form-inline" method="post" role="form" autocomplete="off">{% csrf_token %}
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<input type="text" class="form-control input-lg" name="passwd" placeholder="{% trans "Enter Password" %}" maxlength="24">
|
||||
<input type="text" class="form-control input-lg" name="passwd" placeholder="{% trans "Enter Password" %}" maxlength="24" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
{% ifequal status 5 %}
|
||||
|
|
@ -257,6 +257,7 @@
|
|||
<button class="btn btn-lg btn-success pull-right disabled">{% trans "Reset Root Password" %}</button>
|
||||
{% endifequal %}
|
||||
</form>
|
||||
<p>{% trans "An empty password disable the root password." %}</p>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="sshkeys">
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import crypt
|
|||
from string import letters, digits
|
||||
from random import choice
|
||||
from bisect import insort
|
||||
from jwcrypto import jws, jwk, jwe
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
|
|
@ -288,21 +289,34 @@ def instance(request, compute_id, vname):
|
|||
|
||||
if 'rootpasswd' in request.POST:
|
||||
passwd = request.POST.get('passwd', '')
|
||||
passwd_hash = crypt.crypt(passwd, '$6$kgPoiREy')
|
||||
if passwd:
|
||||
passwd_hash = crypt.crypt(passwd, '$6$%s' % ''.join([choice(letters + digits) for i in xrange(8)]))
|
||||
# if password is empty, disable the root password
|
||||
else:
|
||||
passwd_hash = "*"
|
||||
data = {'action': 'password', 'passwd': passwd_hash, 'vname': vname}
|
||||
|
||||
if conn.get_status() == 5:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((compute.hostname, 16510))
|
||||
s.send(json.dumps(data))
|
||||
result = json.loads(s.recv(1024))
|
||||
s.close()
|
||||
msg = _("Reset root password")
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
if compute.gstfsd_key:
|
||||
key = jwk.JWK(**json.loads(compute.gstfsd_key.strip()))
|
||||
data = jwe.JWE(json.dumps(data), algs=["A256KW", "A256CBC-HS512"])
|
||||
data.add_recipient(key, header='{"alg":"A256KW","enc":"A256CBC-HS512"}')
|
||||
data = jws.JWS(data.serialize())
|
||||
data.add_signature(key, alg="HS512")
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((compute.hostname, 16510))
|
||||
s.send(data.serialize())
|
||||
result = json.loads(s.recv(4096))
|
||||
s.close()
|
||||
msg = _("Reset root password")
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
|
||||
if result['return'] == 'success':
|
||||
messages.append(msg)
|
||||
if result['return'] == 'success':
|
||||
messages.append(msg)
|
||||
else:
|
||||
error_messages.append(result.get('message', msg))
|
||||
else:
|
||||
msg = _("Please import the gstfsd key into this compute. It is in /var/lib/gstfsd/SECRET on %s") % compute.name
|
||||
error_messages.append(msg)
|
||||
else:
|
||||
msg = _("Please shutdow down your instance and then try again")
|
||||
|
|
@ -314,17 +328,26 @@ def instance(request, compute_id, vname):
|
|||
data = {'action': 'publickey', 'key': publickey.keypublic, 'vname': vname}
|
||||
|
||||
if conn.get_status() == 5:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((compute.hostname, 16510))
|
||||
s.send(json.dumps(data))
|
||||
result = json.loads(s.recv(1024))
|
||||
s.close()
|
||||
msg = _("Installed new ssh public key %s" % publickey.keyname)
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
if compute.gstfsd_key:
|
||||
key = jwk.JWK(**json.loads(compute.gstfsd_key.strip()))
|
||||
data = jwe.JWE(json.dumps(data), algs=["A256KW", "A256CBC-HS512"])
|
||||
data.add_recipient(key, header='{"alg":"A256KW","enc":"A256CBC-HS512"}')
|
||||
data = jws.JWS(data.serialize())
|
||||
data.add_signature(key, alg="HS512")
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((compute.hostname, 16510))
|
||||
s.send(data.serialize())
|
||||
result = json.loads(s.recv(4096))
|
||||
s.close()
|
||||
msg = _("Installed new ssh public key %s" % publickey.keyname)
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
|
||||
if result['return'] == 'success':
|
||||
messages.append(msg)
|
||||
if result['return'] == 'success':
|
||||
messages.append(msg)
|
||||
else:
|
||||
error_messages.append(result.get('message', msg))
|
||||
else:
|
||||
msg = _("Please import the gstfsd key into this compute. It is in /var/lib/gstfsd/SECRET on %s") % compute.name
|
||||
error_messages.append(msg)
|
||||
else:
|
||||
msg = _("Please shutdow down your instance and then try again")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue