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
d5cd5030
authored
Jan 27, 2014
by
Kálmán Viktor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard: add new interface to vms
parent
54f1e6ad
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
128 additions
and
10 deletions
+128
-10
circle/dashboard/fixtures/test-vm-fixture.json
+32
-0
circle/dashboard/static/dashboard/dashboard.css
+4
-0
circle/dashboard/static/dashboard/dashboard.js
+5
-0
circle/dashboard/static/dashboard/vm-create.js
+0
-4
circle/dashboard/static/dashboard/vm-details.js
+7
-0
circle/dashboard/templates/dashboard/vm-detail/network.html
+36
-3
circle/dashboard/tests/test_views.py
+19
-0
circle/dashboard/views.py
+25
-3
No files found.
circle/dashboard/fixtures/test-vm-fixture.json
View file @
d5cd5030
...
@@ -1371,5 +1371,37 @@
...
@@ -1371,5 +1371,37 @@
"num_cores"
:
2
,
"num_cores"
:
2
,
"modified"
:
"2013-10-14T07:27:38.192Z"
"modified"
:
"2013-10-14T07:27:38.192Z"
}
}
},
{
"pk"
:
4
,
"model"
:
"firewall.domain"
,
"fields"
:
{
"description"
:
""
,
"created_at"
:
"2013-09-12T14:53:04.035Z"
,
"modified_at"
:
"2013-10-02T14:01:00.318Z"
,
"ttl"
:
600
,
"owner"
:
1
,
"name"
:
"test domain"
}
},
{
"pk"
:
1
,
"model"
:
"firewall.vlan"
,
"fields"
:
{
"comment"
:
""
,
"domain"
:
5
,
"dhcp_pool"
:
""
,
"name"
:
"test vlan"
,
"vid"
:
1
,
"created_at"
:
"2013-09-12T14:54:24.044Z"
,
"modified_at"
:
"2013-10-21T11:19:44.544Z"
,
"owner"
:
null
,
"snat_ip"
:
null
,
"snat_to"
:
[],
"network6"
:
null
,
"network4"
:
"192.168.1.0/24"
,
"reverse_domain"
:
"%(d)d.%(c)d.%(b2)d.%(a)d.in-addr.arpa"
,
"network_type"
:
"public"
,
"description"
:
""
}
}
}
]
]
circle/dashboard/static/dashboard/dashboard.css
View file @
d5cd5030
...
@@ -254,3 +254,7 @@ a.hover-black {
...
@@ -254,3 +254,7 @@ a.hover-black {
margin-top
:
10px
;
margin-top
:
10px
;
display
:
none
;
display
:
none
;
}
}
.dashboard-vm-details-network-h3
{
margin-top
:
20px
;
}
circle/dashboard/static/dashboard/dashboard.js
View file @
d5cd5030
...
@@ -65,6 +65,11 @@ $(function () {
...
@@ -65,6 +65,11 @@ $(function () {
$
(
"a[href="
+
window
.
location
.
hash
+
"]"
).
tab
(
'show'
);
$
(
"a[href="
+
window
.
location
.
hash
+
"]"
).
tab
(
'show'
);
}
}
/* no js compatibility */
$
(
'.no-js-hidden'
).
show
();
$
(
'.js-hidden'
).
hide
();
/* favourite star */
/* favourite star */
$
(
"#dashboard-vm-list"
).
on
(
'click'
,
'.dashboard-vm-favourite'
,
function
(
e
)
{
$
(
"#dashboard-vm-list"
).
on
(
'click'
,
'.dashboard-vm-favourite'
,
function
(
e
)
{
var
star
=
$
(
this
).
children
(
"i"
);
var
star
=
$
(
this
).
children
(
"i"
);
...
...
circle/dashboard/static/dashboard/vm-create.js
View file @
d5cd5030
...
@@ -201,10 +201,6 @@ function vmCreateLoaded() {
...
@@ -201,10 +201,6 @@ function vmCreateLoaded() {
});
});
return
false
;
return
false
;
});
});
/* no js compatibility */
$
(
'.no-js-hidden'
).
show
();
$
(
'.js-hidden'
).
hide
();
}
}
function
vmCreateTemplateChange
(
new_this
)
{
function
vmCreateTemplateChange
(
new_this
)
{
...
...
circle/dashboard/static/dashboard/vm-details.js
View file @
d5cd5030
...
@@ -138,6 +138,13 @@ $(function() {
...
@@ -138,6 +138,13 @@ $(function() {
}
}
return
false
;
return
false
;
});
});
/* add network button */
$
(
"#vm-details-network-add"
).
click
(
function
()
{
$
(
"#vm-details-network-add-for-form"
).
html
(
$
(
"#vm-details-network-add-form"
).
html
());
$
(
'input[name="new_network_managed"]'
).
tooltip
();
return
false
;
});
});
});
...
...
circle/dashboard/templates/dashboard/vm-detail/network.html
View file @
d5cd5030
{% load i18n %}
{% load i18n %}
<h2><a
href=
"#"
class=
"btn btn-success pull-right"
><i
class=
"icon-plus"
></i>
add interface
</a>
<h2>
<a
href=
"#"
id=
"vm-details-network-add"
class=
"btn btn-success pull-right no-js-hidden"
>
<i
class=
"icon-plus"
></i>
add interface
</a>
Interfaces
</h2>
Interfaces
</h2
>
<div
class=
"row"
id=
"vm-details-network-add-for-form"
>
</div>
{% for i in instance.interface_set.all %}
{% for i in instance.interface_set.all %}
<h3
class=
"list-group-item-heading"
>
<h3
class=
"list-group-item-heading
dashboard-vm-details-network-h3
"
>
<i
class=
"icon-{% if i.host %}globe{% else %}link{% endif %}"
></i>
{{ i.vlan }}
<i
class=
"icon-{% if i.host %}globe{% else %}link{% endif %}"
></i>
{{ i.vlan }}
{% if not i.host %}(unmanaged)
<a
href=
"#"
class=
"btn btn-danger btn-xs"
>
remove
</a>
{% endif %}
{% if not i.host %}(unmanaged)
<a
href=
"#"
class=
"btn btn-danger btn-xs"
>
remove
</a>
{% endif %}
</h3>
</h3>
...
@@ -104,3 +110,30 @@ Interfaces</h2>
...
@@ -104,3 +110,30 @@ Interfaces</h2>
</div>
</div>
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
<div
class=
"js-hidden row"
id=
"vm-details-network-add-form"
>
<div
class=
"col-md-12"
>
<div>
<hr
/>
<h3>
{% trans "Add new network interface!" %}
</h3>
<form
method=
"POST"
action=
""
>
{% csrf_token %}
<div
class=
"input-group"
style=
"max-width: 330px;"
>
<select
name=
"new_network_vlan"
class=
"form-control"
>
{% for v in vlans %}
<option
value=
"{{ v.pk }}"
>
{{ v.name }}
</option>
{% endfor %}
</select>
<span
class=
"input-group-addon"
>
<input
type=
"checkbox"
name=
"new_network_managed"
checked=
"checked"
title=
"{% trans "
Managed
network
?"
%}"
>
</span>
<div
class=
"input-group-btn"
>
<button
type=
"submit"
class=
"btn btn-success"
><i
class=
"icon-plus-sign"
></i></button>
</div>
</div>
</form>
<hr
/>
</div>
</div>
</div>
circle/dashboard/tests/test_views.py
View file @
d5cd5030
...
@@ -113,3 +113,22 @@ class VmDetailTest(TestCase):
...
@@ -113,3 +113,22 @@ class VmDetailTest(TestCase):
response
=
c
.
post
(
"/dashboard/vm/1/"
,
{
'change_password'
:
True
})
response
=
c
.
post
(
"/dashboard/vm/1/"
,
{
'change_password'
:
True
})
self
.
assertEqual
(
response
.
status_code
,
403
)
self
.
assertEqual
(
response
.
status_code
,
403
)
self
.
assertEqual
(
password
,
inst
.
pw
)
self
.
assertEqual
(
password
,
inst
.
pw
)
def
test_unpermitted_network_add
(
self
):
c
=
Client
()
self
.
login
(
c
,
"user2"
)
inst
=
Instance
.
objects
.
get
(
pk
=
1
)
inst
.
set_level
(
self
.
u1
,
'owner'
)
response
=
c
.
post
(
"/dashboard/vm/1/"
,
{
'new_network_vlan'
:
1
})
self
.
assertEqual
(
response
.
status_code
,
403
)
def
test_permitted_network_add
(
self
):
c
=
Client
()
self
.
login
(
c
,
"user1"
)
inst
=
Instance
.
objects
.
get
(
pk
=
1
)
inst
.
set_level
(
self
.
u1
,
'owner'
)
interface_count
=
inst
.
interface_set
.
count
()
response
=
c
.
post
(
"/dashboard/vm/1/"
,
{
'new_network_vlan'
:
1
,
'managed'
:
'on'
})
self
.
assertEqual
(
response
.
status_code
,
302
)
self
.
assertEqual
(
inst
.
interface_set
.
count
(),
interface_count
+
1
)
circle/dashboard/views.py
View file @
d5cd5030
...
@@ -27,7 +27,8 @@ from .forms import VmCreateForm, TemplateForm, LeaseForm, NodeForm, HostForm
...
@@ -27,7 +27,8 @@ from .forms import VmCreateForm, TemplateForm, LeaseForm, NodeForm, HostForm
from
.tables
import
(
VmListTable
,
NodeListTable
,
NodeVmListTable
,
from
.tables
import
(
VmListTable
,
NodeListTable
,
NodeVmListTable
,
TemplateListTable
,
LeaseListTable
)
TemplateListTable
,
LeaseListTable
)
from
vm.models
import
(
Instance
,
InstanceTemplate
,
InterfaceTemplate
,
from
vm.models
import
(
Instance
,
InstanceTemplate
,
InterfaceTemplate
,
InstanceActivity
,
Node
,
instance_activity
,
Lease
)
InstanceActivity
,
Node
,
instance_activity
,
Lease
,
Interface
)
from
firewall.models
import
Vlan
,
Host
,
Rule
from
firewall.models
import
Vlan
,
Host
,
Rule
from
storage.models
import
Disk
from
storage.models
import
Disk
from
dashboard.models
import
Favourite
from
dashboard.models
import
Favourite
...
@@ -138,8 +139,9 @@ class VmDetailView(CheckedDetailView):
...
@@ -138,8 +139,9 @@ class VmDetailView(CheckedDetailView):
ia
=
InstanceActivity
.
objects
.
filter
(
ia
=
InstanceActivity
.
objects
.
filter
(
instance
=
self
.
object
,
parent
=
None
instance
=
self
.
object
,
parent
=
None
)
.
order_by
(
'-started'
)
.
select_related
()
)
.
order_by
(
'-started'
)
.
select_related
()
context
[
'activity'
]
=
ia
context
[
'activity'
]
=
ia
context
[
'vlans'
]
=
Vlan
.
objects
.
all
()
# TODO acl
context
[
'acl'
]
=
get_acl_data
(
instance
)
context
[
'acl'
]
=
get_acl_data
(
instance
)
return
context
return
context
...
@@ -153,7 +155,8 @@ class VmDetailView(CheckedDetailView):
...
@@ -153,7 +155,8 @@ class VmDetailView(CheckedDetailView):
'new_name'
:
self
.
__set_name
,
'new_name'
:
self
.
__set_name
,
'new_tag'
:
self
.
__add_tag
,
'new_tag'
:
self
.
__add_tag
,
'to_remove'
:
self
.
__remove_tag
,
'to_remove'
:
self
.
__remove_tag
,
'port'
:
self
.
__add_port
'port'
:
self
.
__add_port
,
'new_network_vlan'
:
self
.
__new_network
,
}
}
for
k
,
v
in
options
.
iteritems
():
for
k
,
v
in
options
.
iteritems
():
...
@@ -288,6 +291,25 @@ class VmDetailView(CheckedDetailView):
...
@@ -288,6 +291,25 @@ class VmDetailView(CheckedDetailView):
return
redirect
(
reverse_lazy
(
"dashboard.views.detail"
,
return
redirect
(
reverse_lazy
(
"dashboard.views.detail"
,
kwargs
=
{
'pk'
:
self
.
get_object
()
.
pk
}))
kwargs
=
{
'pk'
:
self
.
get_object
()
.
pk
}))
def
__new_network
(
self
,
request
):
self
.
object
=
self
.
get_object
()
if
not
self
.
object
.
has_level
(
request
.
user
,
'owner'
):
raise
PermissionDenied
()
vlan
=
Vlan
.
objects
.
get
(
pk
=
request
.
POST
.
get
(
"new_network_vlan"
))
managed
=
request
.
POST
.
get
(
"new_network_managed"
)
managed
=
False
if
managed
is
None
else
True
try
:
Interface
.
create
(
vlan
=
vlan
,
instance
=
self
.
object
,
managed
=
managed
,
owner
=
request
.
user
)
messages
.
success
(
request
,
_
(
"Successfully added new interface!"
))
except
Exception
,
e
:
error
=
u' '
.
join
(
e
.
messages
)
messages
.
error
(
request
,
error
)
return
redirect
(
"
%
s#network"
%
reverse_lazy
(
"dashboard.views.detail"
,
kwargs
=
{
'pk'
:
self
.
object
.
pk
}))
class
NodeDetailView
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
DetailView
):
class
NodeDetailView
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
DetailView
):
template_name
=
"dashboard/node-detail.html"
template_name
=
"dashboard/node-detail.html"
...
...
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