Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
CIRCLE
/
cloud
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
94
Merge Requests
10
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
6c393877
authored
Feb 13, 2013
by
Dudás Ádám
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
one: enforcing guidelines
parent
059a0c45
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
156 additions
and
152 deletions
+156
-152
firewall/views.py
+1
-1
one/models.py
+155
-149
one/util.py
+0
-2
No files found.
firewall/views.py
View file @
6c393877
...
...
@@ -19,7 +19,7 @@ def reload_firewall(request):
if
request
.
user
.
is_authenticated
():
if
request
.
user
.
is_superuser
:
html
=
((
_
(
"Dear
%
s, you've signed in as administrator!"
)
%
request
.
user
.
username
)
+
"<br>"
+
request
.
user
.
username
)
+
"<br
/
>"
+
_
(
"Reloading in 10 seconds..."
))
ReloadTask
.
delay
()
else
:
...
...
one/models.py
View file @
6c393877
...
...
@@ -22,38 +22,39 @@ import subprocess, tempfile, os, stat, re, base64, struct
logger
=
logging
.
getLogger
(
__name__
)
pwgen
=
User
.
objects
.
make_random_password
"""
User creation hook: create cloud details object
"""
def
create_user_profile
(
sender
,
instance
,
created
,
**
kwargs
):
"""User creation hook: create cloud details object"""
if
created
:
d
=
UserCloudDetails
(
user
=
instance
)
d
.
clean
()
d
.
save
()
post_save
.
connect
(
create_user_profile
,
sender
=
User
)
d
=
UserCloudDetails
(
user
=
instance
)
d
.
clean
()
d
.
save
()
post_save
.
connect
(
create_user_profile
,
sender
=
User
)
"""
Cloud related details of a user
"""
class
UserCloudDetails
(
models
.
Model
):
user
=
models
.
ForeignKey
(
User
,
null
=
False
,
blank
=
False
,
unique
=
True
,
verbose_name
=
_
(
'user'
))
"""Cloud related details of a user."""
user
=
models
.
ForeignKey
(
User
,
null
=
False
,
blank
=
False
,
unique
=
True
,
verbose_name
=
_
(
'user'
))
smb_password
=
models
.
CharField
(
max_length
=
20
,
verbose_name
=
_
(
'Samba password'
),
help_text
=
_
(
'Generated password for accessing store from Windows.'
))
ssh_key
=
models
.
ForeignKey
(
'SshKey'
,
null
=
True
,
verbose_name
=
_
(
'SSH key (public)'
),
help_text
=
_
(
'Generated SSH public key for accessing store from Linux.'
))
ssh_private_key
=
models
.
TextField
(
verbose_name
=
_
(
'SSH key (private)'
),
null
=
True
,
help_text
=
_
(
'Generated SSH private key for accessing store from Linux.'
))
share_quota
=
models
.
IntegerField
(
verbose_name
=
_
(
'share quota'
),
default
=
0
)
instance_quota
=
models
.
IntegerField
(
verbose_name
=
_
(
'instance quota'
),
default
=
20
)
disk_quota
=
models
.
IntegerField
(
verbose_name
=
_
(
'disk quota'
),
default
=
2048
,
help_text
=
_
(
'Disk quota in mebibytes.'
))
"""
Delete old SSH key pair and generate new one.
"""
help_text
=
_
(
'Generated password for accessing store from '
'Windows.'
))
ssh_key
=
models
.
ForeignKey
(
'SshKey'
,
null
=
True
,
verbose_name
=
_
(
'SSH key (public)'
),
help_text
=
_
(
'Generated SSH public key for accessing store from '
'Linux.'
))
ssh_private_key
=
models
.
TextField
(
verbose_name
=
_
(
'SSH key (private)'
),
null
=
True
,
help_text
=
_
(
'Generated SSH private key for '
'accessing store from Linux.'
))
share_quota
=
models
.
IntegerField
(
verbose_name
=
_
(
'share quota'
),
default
=
0
)
instance_quota
=
models
.
IntegerField
(
verbose_name
=
_
(
'instance quota'
),
default
=
20
)
disk_quota
=
models
.
IntegerField
(
verbose_name
=
_
(
'disk quota'
),
default
=
2048
,
help_text
=
_
(
'Disk quota in mebibytes.'
))
def
reset_keys
(
self
):
"""Delete old SSH key pair and generate new one."""
pri
,
pub
=
keygen
()
self
.
ssh_private_key
=
pri
...
...
@@ -65,10 +66,8 @@ class UserCloudDetails(models.Model):
self
.
ssh_key_id
=
self
.
ssh_key
.
id
self
.
save
()
"""
Generate new Samba password.
"""
def
reset_smb
(
self
):
"""Generate new Samba password."""
self
.
smb_password
=
pwgen
()
def
get_weighted_instance_count
(
self
):
...
...
@@ -78,15 +77,14 @@ class UserCloudDetails(models.Model):
c
=
c
+
i
.
template
.
instance_type
.
credit
return
c
def
get_instance_pc
(
self
):
return
100
*
self
.
get_weighted_instance_count
()
/
self
.
instance_quota
return
100
*
self
.
get_weighted_instance_count
()
/
self
.
instance_quota
def
get_weighted_share_count
(
self
):
c
=
0
for
i
in
Share
.
objects
.
filter
(
owner
=
self
.
user
)
.
all
():
c
=
c
+
i
.
template
.
instance_type
.
credit
*
i
.
instance_limit
return
c
def
get_share_pc
(
self
):
return
100
*
self
.
get_weighted_share_count
()
/
self
.
share_quota
return
100
*
self
.
get_weighted_share_count
()
/
self
.
share_quota
def
set_quota
(
sender
,
instance
,
created
,
**
kwargs
):
if
not
StoreApi
.
userexist
(
instance
.
user
.
username
):
...
...
@@ -98,11 +96,13 @@ def set_quota(sender, instance, created, **kwargs):
key_list
.
append
(
key
.
key
)
except
:
pass
#Create user
if
not
StoreApi
.
createuser
(
instance
.
user
.
username
,
password
,
key_list
,
quota
):
# Create user
if
not
StoreApi
.
createuser
(
instance
.
user
.
username
,
password
,
key_list
,
quota
):
pass
else
:
StoreApi
.
set_quota
(
instance
.
user
.
username
,
instance
.
disk_quota
*
1024
)
StoreApi
.
set_quota
(
instance
.
user
.
username
,
instance
.
disk_quota
*
1024
)
post_save
.
connect
(
set_quota
,
sender
=
UserCloudDetails
)
def
reset_keys
(
sender
,
instance
,
created
,
**
kwargs
):
...
...
@@ -112,10 +112,8 @@ def reset_keys(sender, instance, created, **kwargs):
post_save
.
connect
(
reset_keys
,
sender
=
UserCloudDetails
)
"""
Validate OpenSSH keys (length and type).
"""
class
OpenSshKeyValidator
(
object
):
"""Validate OpenSSH keys (length and type)."""
valid_types
=
[
'ssh-rsa'
,
'ssh-dsa'
]
def
__init__
(
self
,
types
=
None
):
...
...
@@ -127,7 +125,8 @@ class OpenSshKeyValidator(object):
value
=
"
%
s comment"
%
value
type
,
key_string
,
comment
=
value
.
split
(
None
,
2
)
if
type
not
in
self
.
valid_types
:
raise
ValidationError
(
_
(
'OpenSSH key type
%
s is not supported.'
)
%
type
)
raise
ValidationError
(
_
(
'OpenSSH key type
%
s is not '
'supported.'
)
%
type
)
data
=
base64
.
decodestring
(
key_string
)
int_len
=
4
str_len
=
struct
.
unpack
(
'>I'
,
data
[:
int_len
])[
0
]
...
...
@@ -138,15 +137,15 @@ class OpenSshKeyValidator(object):
except
:
raise
ValidationError
(
_
(
'Invalid OpenSSH public key.'
))
"""
SSH public key (in OpenSSH format).
"""
class
SshKey
(
models
.
Model
):
"""SSH public key (in OpenSSH format)."""
user
=
models
.
ForeignKey
(
User
,
null
=
False
,
blank
=
False
)
key
=
models
.
CharField
(
max_length
=
2000
,
verbose_name
=
_
(
'SSH key'
),
help_text
=
_
(
'<a href="/info/ssh/">SSH public key in OpenSSH format</a> used for shell and store login '
'(2048+ bit RSA preferred). Example: <code>ssh-rsa AAAAB...QtQ== '
'john</code>.'
),
validators
=
[
OpenSshKeyValidator
()])
help_text
=
_
(
'<a href="/info/ssh/">SSH public key in OpenSSH '
'format</a> used for shell and store login '
'(2048+ bit RSA preferred). Example: '
'<code>ssh-rsa AAAAB...QtQ== john</code>.'
),
validators
=
[
OpenSshKeyValidator
()])
def
__unicode__
(
self
):
try
:
...
...
@@ -156,62 +155,75 @@ class SshKey(models.Model):
return
u"
%
s (
%
s)"
%
(
keycomment
,
self
.
user
)
TEMPLATE_STATES
=
((
"INIT"
,
_
(
'init'
)),
(
"PREP"
,
_
(
'perparing'
)),
(
"SAVE"
,
_
(
'saving'
)),
(
"READY"
,
_
(
'ready'
)))
TYPES
=
{
"LAB"
:
{
"verbose_name"
:
_
(
'lab'
),
"id"
:
"LAB"
,
"suspend"
:
td
(
hours
=
5
),
"delete"
:
td
(
days
=
15
),
"help_text"
:
_
(
'For lab or home work with short life time.'
)},
"PROJECT"
:
{
"verbose_name"
:
_
(
'project'
),
"id"
:
"PROJECT"
,
"suspend"
:
td
(
weeks
=
5
),
"delete"
:
td
(
days
=
366
/
2
),
"help_text"
:
_
(
'For project work.'
)},
"SERVER"
:
{
"verbose_name"
:
_
(
'server'
),
"id"
:
"SERVER"
,
"suspend"
:
td
(
days
=
365
),
"delete"
:
None
,
"help_text"
:
_
(
'For long term server use.'
)},
TEMPLATE_STATES
=
((
"INIT"
,
_
(
'init'
)),
(
"PREP"
,
_
(
'perparing'
)),
(
"SAVE"
,
_
(
'saving'
)),
(
"READY"
,
_
(
'ready'
)))
TYPES
=
{
"LAB"
:
{
"verbose_name"
:
_
(
'lab'
),
"id"
:
"LAB"
,
"suspend"
:
td
(
hours
=
5
),
"delete"
:
td
(
days
=
15
),
"help_text"
:
_
(
'For lab or homework with short lifetime.'
)},
"PROJECT"
:
{
"verbose_name"
:
_
(
'project'
),
"id"
:
"PROJECT"
,
"suspend"
:
td
(
weeks
=
5
),
"delete"
:
td
(
days
=
366
/
2
),
"help_text"
:
_
(
'For project work.'
)},
"SERVER"
:
{
"verbose_name"
:
_
(
'server'
),
"id"
:
"SERVER"
,
"suspend"
:
td
(
days
=
365
),
"delete"
:
None
,
"help_text"
:
_
(
'For long-term server use.'
)},
}
TYPES_L
=
sorted
(
TYPES
.
values
(),
key
=
lambda
m
:
m
[
"suspend"
])
TYPES_C
=
tuple
([(
i
[
0
],
i
[
1
][
"verbose_name"
])
for
i
in
TYPES
.
items
()])
class
Share
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
100
,
verbose_name
=
_
(
'name'
))
description
=
models
.
TextField
(
verbose_name
=
_
(
'description'
))
template
=
models
.
ForeignKey
(
'Template'
,
null
=
False
,
blank
=
False
)
group
=
models
.
ForeignKey
(
Group
,
null
=
False
,
blank
=
False
)
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'created at'
))
type
=
models
.
CharField
(
choices
=
TYPES_C
,
max_length
=
10
,
blank
=
False
,
null
=
False
)
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'created at'
))
type
=
models
.
CharField
(
choices
=
TYPES_C
,
max_length
=
10
,
blank
=
False
,
null
=
False
)
instance_limit
=
models
.
IntegerField
(
verbose_name
=
_
(
'instance limit'
),
help_text
=
_
(
'Maximal count of instances launchable for this share.'
))
help_text
=
_
(
'Maximal count of instances launchable for this '
'share.'
))
per_user_limit
=
models
.
IntegerField
(
verbose_name
=
_
(
'per user limit'
),
help_text
=
_
(
'Maximal count of instances launchable by a single user.'
))
help_text
=
_
(
'Maximal count of instances launchable by a single '
'user.'
))
owner
=
models
.
ForeignKey
(
User
,
null
=
True
,
blank
=
True
)
def
get_type
(
self
):
t
=
TYPES
[
self
.
type
]
t
[
'deletex'
]
=
datetime
.
now
()
+
td
(
seconds
=
1
)
+
t
[
'delete'
]
if
t
[
'delete'
]
else
None
t
[
'suspendx'
]
=
datetime
.
now
()
+
td
(
seconds
=
1
)
+
t
[
'suspend'
]
if
t
[
'suspend'
]
else
None
t
[
'deletex'
]
=
(
datetime
.
now
()
+
td
(
seconds
=
1
)
+
t
[
'delete'
]
if
t
[
'delete'
]
else
None
)
t
[
'suspendx'
]
=
(
datetime
.
now
()
+
td
(
seconds
=
1
)
+
t
[
'suspend'
]
if
t
[
'suspend'
]
else
None
)
return
t
def
get_running_or_stopped
(
self
,
user
=
None
):
running
=
Instance
.
objects
.
all
()
.
exclude
(
state
=
'DONE'
)
.
filter
(
share
=
self
)
running
=
(
Instance
.
objects
.
all
()
.
exclude
(
state
=
'DONE'
)
.
filter
(
share
=
self
))
if
user
:
return
running
.
filter
(
owner
=
user
)
.
count
()
else
:
return
running
.
count
()
def
get_running
(
self
,
user
=
None
):
running
=
Instance
.
objects
.
all
()
.
exclude
(
state
=
'DONE'
)
.
exclude
(
state
=
'STOPPED'
)
.
filter
(
share
=
self
)
running
=
(
Instance
.
objects
.
all
()
.
exclude
(
state
=
'DONE'
)
.
exclude
(
state
=
'STOPPED'
)
.
filter
(
share
=
self
))
if
user
:
return
running
.
filter
(
owner
=
user
)
.
count
()
else
:
return
running
.
count
()
def
get_instance_pc
(
self
):
return
float
(
self
.
get_running
())
/
self
.
instance_limit
*
100
"""
Virtual disks automatically synchronized with OpenNebula.
"""
class
Disk
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
100
,
unique
=
True
,
verbose_name
=
_
(
'name'
))
"""Virtual disks automatically synchronized with OpenNebula."""
name
=
models
.
CharField
(
max_length
=
100
,
unique
=
True
,
verbose_name
=
_
(
'name'
))
"""
Get and register virtual disks from OpenNebula.
"""
@classmethod
def
update
(
cls
):
"""Get and register virtual disks from OpenNebula."""
import
subprocess
proc
=
subprocess
.
Popen
([
"/opt/occi.sh"
,
"storage"
,
"list"
],
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
proc
=
subprocess
.
Popen
([
"/opt/occi.sh"
,
"storage"
,
"list"
],
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
(
out
,
err
)
=
proc
.
communicate
()
from
xml.dom.minidom
import
parse
,
parseString
x
=
parseString
(
out
)
...
...
@@ -235,22 +247,21 @@ class Disk(models.Model):
class
Meta
:
ordering
=
[
'name'
]
"""
Virtual networks automatically synchronized with OpenNebula.
"""
class
Network
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
100
,
unique
=
True
,
verbose_name
=
_
(
'name'
))
nat
=
models
.
BooleanField
(
verbose_name
=
_
(
'NAT'
),
help_text
=
_
(
'If network address translation is done.'
))
public
=
models
.
BooleanField
(
verbose_name
=
_
(
'public'
),
help_text
=
_
(
'If internet gateway is available.'
))
"""Virtual networks automatically synchronized with OpenNebula."""
name
=
models
.
CharField
(
max_length
=
100
,
unique
=
True
,
verbose_name
=
_
(
'name'
))
nat
=
models
.
BooleanField
(
verbose_name
=
_
(
'NAT'
),
help_text
=
_
(
'If network address translation is done.'
))
public
=
models
.
BooleanField
(
verbose_name
=
_
(
'public'
),
help_text
=
_
(
'If internet gateway is available.'
))
"""
Get and register virtual networks from OpenNebula.
"""
@classmethod
def
update
(
cls
):
"""Get and register virtual networks from OpenNebula."""
import
subprocess
proc
=
subprocess
.
Popen
([
"/opt/occi.sh"
,
"network"
,
"list"
],
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
proc
=
subprocess
.
Popen
([
"/opt/occi.sh"
,
"network"
,
"list"
],
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
(
out
,
err
)
=
proc
.
communicate
()
from
xml.dom.minidom
import
parse
,
parseString
x
=
parseString
(
out
)
...
...
@@ -273,10 +284,8 @@ class Network(models.Model):
class
Meta
:
ordering
=
[
'name'
]
"""
Instance types in OCCI configuration (manually synchronized).
"""
class
InstanceType
(
models
.
Model
):
"""Instance types in OCCI configuration (manually synchronized)."""
name
=
models
.
CharField
(
max_length
=
100
,
unique
=
True
,
verbose_name
=
_
(
'name'
))
CPU
=
models
.
IntegerField
(
help_text
=
_
(
'CPU cores.'
))
...
...
@@ -288,23 +297,24 @@ class InstanceType(models.Model):
class
Meta
:
ordering
=
[
'credit'
]
TEMPLATE_STATES
=
((
'NEW'
,
_
(
'new'
)),
(
'SAVING'
,
_
(
'saving'
)),
(
'READY'
,
_
(
'ready'
)),
)
"""
Virtual machine template specifying OS, disk, type and network.
"""
TEMPLATE_STATES
=
((
'NEW'
,
_
(
'new'
)),
(
'SAVING'
,
_
(
'saving'
)),
(
'READY'
,
_
(
'ready'
)),
)
class
Template
(
models
.
Model
):
"""Virtual machine template specifying OS, disk, type and network."""
name
=
models
.
CharField
(
max_length
=
100
,
unique
=
True
,
verbose_name
=
_
(
'name'
))
access_type
=
models
.
CharField
(
max_length
=
10
,
choices
=
[(
'rdp'
,
'rdp'
),
(
'nx'
,
'nx'
),
(
'ssh'
,
'ssh'
)],
verbose_name
=
_
(
'access method'
))
disk
=
models
.
ForeignKey
(
Disk
,
verbose_name
=
_
(
'disk'
))
instance_type
=
models
.
ForeignKey
(
InstanceType
,
verbose_name
=
_
(
'instance type'
))
instance_type
=
models
.
ForeignKey
(
InstanceType
,
verbose_name
=
_
(
'instance type'
))
network
=
models
.
ForeignKey
(
Network
,
verbose_name
=
_
(
'network'
))
owner
=
models
.
ForeignKey
(
User
,
verbose_name
=
_
(
'owner'
))
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'created at'
))
state
=
models
.
CharField
(
max_length
=
10
,
choices
=
TEMPLATE_STATES
,
default
=
'NEW'
)
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'created at'
))
state
=
models
.
CharField
(
max_length
=
10
,
choices
=
TEMPLATE_STATES
,
default
=
'NEW'
)
public
=
models
.
BooleanField
(
verbose_name
=
_
(
'public'
),
default
=
False
,
help_text
=
_
(
'If other users can derive templates of this one.'
))
description
=
models
.
TextField
(
verbose_name
=
_
(
'description'
),
blank
=
True
)
...
...
@@ -336,56 +346,57 @@ class Template(models.Model):
verbose_name
=
_
(
'template'
)
verbose_name_plural
=
_
(
'templates'
)
"""
Virtual machine instance.
"""
class
Instance
(
models
.
Model
):
"""Virtual machine instance."""
name
=
models
.
CharField
(
max_length
=
100
,
unique
=
True
,
verbose_name
=
_
(
'name'
),
null
=
True
,
blank
=
True
)
ip
=
models
.
IPAddressField
(
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'IP address'
))
ip
=
models
.
IPAddressField
(
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'IP address'
))
template
=
models
.
ForeignKey
(
Template
,
verbose_name
=
_
(
'template'
))
owner
=
models
.
ForeignKey
(
User
,
verbose_name
=
_
(
'owner'
))
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'created at'
))
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'created at'
))
state
=
models
.
CharField
(
max_length
=
20
,
choices
=
[(
'DEPLOYABLE'
,
_
(
'deployable'
)),
(
'PENDING'
,
_
(
'pending'
)),
(
'DONE'
,
_
(
'done'
)),
(
'ACTIVE'
,
_
(
'active'
)),
(
'UNKNOWN'
,
_
(
'unknown'
)),
(
'STOPPED'
,
_
(
'suspended'
)),
(
'FAILED'
,
_
(
'failed'
))],
default
=
'DEPLOYABLE'
)
(
'PENDING'
,
_
(
'pending'
)),
(
'DONE'
,
_
(
'done'
)),
(
'ACTIVE'
,
_
(
'active'
)),
(
'UNKNOWN'
,
_
(
'unknown'
)),
(
'STOPPED'
,
_
(
'suspended'
)),
(
'FAILED'
,
_
(
'failed'
))],
default
=
'DEPLOYABLE'
)
active_since
=
models
.
DateTimeField
(
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'active since'
),
help_text
=
_
(
'Time stamp of successful boot report.'
))
firewall_host
=
models
.
ForeignKey
(
Host
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'host in firewall'
))
pw
=
models
.
CharField
(
max_length
=
20
,
verbose_name
=
_
(
'password'
),
help_text
=
_
(
'Original password of instance'
))
one_id
=
models
.
IntegerField
(
unique
=
True
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'OpenNebula ID'
))
share
=
models
.
ForeignKey
(
'Share'
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'share'
))
time_of_suspend
=
models
.
DateTimeField
(
default
=
None
,
verbose_name
=
_
(
'time of suspend'
),
null
=
True
,
blank
=
False
)
time_of_delete
=
models
.
DateTimeField
(
default
=
None
,
verbose_name
=
_
(
'time of delete'
),
null
=
True
,
blank
=
False
)
firewall_host
=
models
.
ForeignKey
(
Host
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'host in firewall'
))
pw
=
models
.
CharField
(
max_length
=
20
,
verbose_name
=
_
(
'password'
),
help_text
=
_
(
'Original password of instance'
))
one_id
=
models
.
IntegerField
(
unique
=
True
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'OpenNebula ID'
))
share
=
models
.
ForeignKey
(
'Share'
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'share'
))
time_of_suspend
=
models
.
DateTimeField
(
default
=
None
,
verbose_name
=
_
(
'time of suspend'
),
null
=
True
,
blank
=
False
)
time_of_delete
=
models
.
DateTimeField
(
default
=
None
,
verbose_name
=
_
(
'time of delete'
),
null
=
True
,
blank
=
False
)
waiting
=
models
.
BooleanField
(
default
=
False
)
"""
Get public port number for default access method.
"""
def
get_port
(
self
):
"""Get public port number for default access method."""
proto
=
self
.
template
.
access_type
if
self
.
template
.
network
.
nat
:
return
{
"rdp"
:
23000
,
"nx"
:
22000
,
"ssh"
:
22000
}[
proto
]
+
int
(
self
.
ip
.
split
(
'.'
)[
2
])
*
256
+
int
(
self
.
ip
.
split
(
'.'
)[
3
])
else
:
return
{
"rdp"
:
3389
,
"nx"
:
22
,
"ssh"
:
22
}[
proto
]
"""
Get public hostname.
"""
def
get_connect_host
(
self
):
"""Get public hostname."""
if
self
.
template
.
network
.
nat
:
return
'cloud'
else
:
return
self
.
ip
"""
Get access parameters in URI format.
"""
def
get_connect_uri
(
self
):
"""Get access parameters in URI format."""
try
:
proto
=
self
.
template
.
access_type
if
proto
==
'ssh'
:
...
...
@@ -393,31 +404,31 @@ class Instance(models.Model):
port
=
self
.
get_port
()
host
=
self
.
get_connect_host
()
pw
=
self
.
pw
return
"
%(proto)
s:cloud:
%(pw)
s:
%(host)
s:
%(port)
d"
%
{
"port"
:
port
,
"proto"
:
proto
,
"host"
:
self
.
firewall_host
.
pub_ipv4
,
"pw"
:
pw
}
return
(
"
%(proto)
s:cloud:
%(pw)
s:
%(host)
s:
%(port)
d"
%
{
"port"
:
port
,
"proto"
:
proto
,
"pw"
:
pw
,
"host"
:
self
.
firewall_host
.
pub_ipv4
})
except
:
return
def
__unicode__
(
self
):
return
self
.
name
"""
Get and update VM state from OpenNebula.
"""
def
update_state
(
self
):
"""Get and update VM state from OpenNebula."""
import
subprocess
if
not
self
.
one_id
:
return
proc
=
subprocess
.
Popen
([
"/opt/occi.sh"
,
"compute"
,
"show"
,
"
%
d"
%
self
.
one_id
],
stdout
=
subprocess
.
PIPE
)
"
%
d"
%
self
.
one_id
],
stdout
=
subprocess
.
PIPE
)
(
out
,
err
)
=
proc
.
communicate
()
x
=
None
old_state
=
self
.
state
try
:
from
xml.dom.minidom
import
parse
,
parseString
x
=
parseString
(
out
)
self
.
vnet_ip
=
x
.
getElementsByTagName
(
"IP"
)[
0
]
.
childNodes
[
0
]
.
nodeValue
.
split
(
'.'
)[
3
]
self
.
vnet_ip
=
(
x
.
getElementsByTagName
(
"IP"
)[
0
]
.
childNodes
[
0
]
.
nodeValue
.
split
(
'.'
)[
3
])
state
=
x
.
getElementsByTagName
(
"STATE"
)[
0
]
.
childNodes
[
0
]
.
nodeValue
self
.
state
=
state
except
:
...
...
@@ -429,10 +440,8 @@ class Instance(models.Model):
self
.
check_if_is_save_as_done
()
return
x
"""
Get age of VM in seconds.
"""
def
get_age
(
self
):
"""Get age of VM in seconds."""
from
datetime
import
datetime
age
=
0
try
:
...
...
@@ -446,11 +455,9 @@ class Instance(models.Model):
def
get_absolute_url
(
self
):
return
(
'vm_show'
,
None
,
{
'iid'
:
self
.
id
})
"""
Submit a new instance to OpenNebula.
"""
@classmethod
def
submit
(
cls
,
template
,
owner
,
extra
=
""
,
share
=
None
):
"""Submit a new instance to OpenNebula."""
from
django.template.defaultfilters
import
escape
out
=
""
inst
=
Instance
(
pw
=
pwgen
(),
template
=
template
,
owner
=
owner
,
share
=
share
)
...
...
@@ -498,9 +505,8 @@ class Instance(models.Model):
f
.
write
(
tpl
)
f
.
close
()
import
subprocess
proc
=
subprocess
.
Popen
([
"/opt/occi.sh"
,
"compute"
,
"create"
,
f
.
name
],
stdout
=
subprocess
.
PIPE
)
proc
=
subprocess
.
Popen
([
"/opt/occi.sh"
,
"compute"
,
"create"
,
f
.
name
],
stdout
=
subprocess
.
PIPE
)
(
out
,
err
)
=
proc
.
communicate
()
os
.
unlink
(
f
.
name
)
from
xml.dom.minidom
import
parse
,
parseString
...
...
@@ -508,12 +514,16 @@ class Instance(models.Model):
x
=
parseString
(
out
)
except
:
raise
Exception
(
"Unable to create VM instance."
)
inst
.
one_id
=
int
(
x
.
getElementsByTagName
(
"ID"
)[
0
]
.
childNodes
[
0
]
.
nodeValue
)
inst
.
one_id
=
int
(
x
.
getElementsByTagName
(
"ID"
)[
0
]
.
childNodes
[
0
]
.
nodeValue
)
inst
.
ip
=
x
.
getElementsByTagName
(
"IP"
)[
0
]
.
childNodes
[
0
]
.
nodeValue
inst
.
name
=
"
%(neptun)
s
%(template)
s (
%(id)
d)"
%
{
'neptun'
:
owner
.
username
,
'template'
:
template
.
name
,
'id'
:
inst
.
one_id
}
inst
.
name
=
(
"
%(neptun)
s
%(template)
s (
%(id)
d)"
%
{
'neptun'
:
owner
.
username
,
'template'
:
template
.
name
,
'id'
:
inst
.
one_id
})
inst
.
save
()
inst
.
update_state
()
host
=
Host
(
vlan
=
Vlan
.
objects
.
get
(
name
=
template
.
network
.
name
),
owner
=
owner
,
shared_ip
=
True
)
host
=
Host
(
vlan
=
Vlan
.
objects
.
get
(
name
=
template
.
network
.
name
),
owner
=
owner
,
shared_ip
=
True
)
host
.
hostname
=
u"id-
%
d_user-
%
s"
%
(
inst
.
id
,
owner
.
username
)
host
.
mac
=
x
.
getElementsByTagName
(
"MAC"
)[
0
]
.
childNodes
[
0
]
.
nodeValue
host
.
ipv4
=
inst
.
ip
...
...
@@ -527,17 +537,16 @@ class Instance(models.Model):
i
.
delete
()
host
.
save
()
host
.
enable_net
()
host
.
add_port
(
"tcp"
,
inst
.
get_port
(),
{
"rdp"
:
3389
,
"nx"
:
22
,
"ssh"
:
22
}[
inst
.
template
.
access_type
])
host
.
add_port
(
"tcp"
,
inst
.
get_port
(),
{
"rdp"
:
3389
,
"nx"
:
22
,
"ssh"
:
22
}[
inst
.
template
.
access_type
])
inst
.
firewall_host
=
host
inst
.
save
()
return
inst
"""
Delete host in OpenNebula.
"""
def
one_delete
(
self
):
proc
=
subprocess
.
Popen
([
"/opt/occi.sh"
,
"compute"
,
"delete"
,
"
%
d"
%
self
.
one_id
],
stdout
=
subprocess
.
PIPE
)
"""Delete host in OpenNebula."""
proc
=
subprocess
.
Popen
([
"/opt/occi.sh"
,
"compute"
,
"delete"
,
"
%
d"
%
self
.
one_id
],
stdout
=
subprocess
.
PIPE
)
(
out
,
err
)
=
proc
.
communicate
()
self
.
firewall_host_delete
()
...
...
@@ -561,17 +570,14 @@ class Instance(models.Model):
f
.
write
(
tpl
)
f
.
close
()
import
subprocess
proc
=
subprocess
.
Popen
([
"/opt/occi.sh"
,
"compute"
,
"update"
,
proc
=
subprocess
.
Popen
([
"/opt/occi.sh"
,
"compute"
,
"update"
,
f
.
name
],
stdout
=
subprocess
.
PIPE
)
(
out
,
err
)
=
proc
.
communicate
()
os
.
unlink
(
f
.
name
)
print
"out: "
+
out
"""
Change host state in OpenNebula.
"""
def
_change_state
(
self
,
new_state
):
"""Change host state in OpenNebula."""
self
.
_update_vm
(
"<STATE>"
+
new_state
+
"</STATE>"
)
def
stop
(
self
):
...
...
@@ -593,9 +599,7 @@ class Instance(models.Model):
raise
ValueError
(
'No such expiration type.'
)
self
.
save
()
def
save_as
(
self
):
"""
Save image and shut down.
"""
"""Save image and shut down."""
imgname
=
"template-
%
d-
%
d"
%
(
self
.
template
.
id
,
self
.
id
)
self
.
_update_vm
(
'<DISK id="0"><SAVE_AS name="
%
s"/></DISK>'
%
imgname
)
self
.
_change_state
(
"SHUTDOWN"
)
...
...
@@ -630,7 +634,8 @@ def delete_instance(sender, instance, using, **kwargs):
instance
.
firewall_host_delete
()
except
:
pass
post_delete
.
connect
(
delete_instance
,
sender
=
Instance
,
dispatch_uid
=
"delete_instance"
)
post_delete
.
connect
(
delete_instance
,
sender
=
Instance
,
dispatch_uid
=
"delete_instance"
)
def
delete_instance_pre
(
sender
,
instance
,
using
,
**
kwargs
):
try
:
...
...
@@ -638,5 +643,6 @@ def delete_instance_pre(sender, instance, using, **kwargs):
instance
.
check_if_is_save_as_done
()
except
:
pass
pre_delete
.
connect
(
delete_instance_pre
,
sender
=
Instance
,
dispatch_uid
=
"delete_instance_pre"
)
pre_delete
.
connect
(
delete_instance_pre
,
sender
=
Instance
,
dispatch_uid
=
"delete_instance_pre"
)
one/util.py
View file @
6c393877
...
...
@@ -30,5 +30,3 @@ def keygen(length=1024):
pub
=
'ssh-rsa
%
s'
%
(
base64
.
b64encode
(
base64
.
b16decode
(
ssh_rsa
.
upper
())),
)
return
key
.
exportKey
(),
"
%
s
%
s"
%
(
pub
,
"cloud-
%
s"
%
date
.
today
())
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment