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