Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gelencsér Szabolcs
/
circlestack
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
651a6105
authored
Dec 03, 2013
by
Kálmán Viktor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard: open and close ports
parent
d798a61b
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
171 additions
and
41 deletions
+171
-41
circle/dashboard/static/dashboard/dashboard.css
+14
-0
circle/dashboard/static/dashboard/vm-details.js
+31
-0
circle/dashboard/templates/dashboard/confirm/ajax-delete.html
+5
-1
circle/dashboard/templates/dashboard/confirm/base-delete.html
+12
-4
circle/dashboard/templates/dashboard/vm-detail-network-port-add.html
+18
-17
circle/dashboard/templates/dashboard/vm-detail-network.html
+12
-17
circle/dashboard/urls.py
+3
-1
circle/dashboard/views.py
+76
-1
No files found.
circle/dashboard/static/dashboard/dashboard.css
View file @
651a6105
...
@@ -194,3 +194,17 @@ body {
...
@@ -194,3 +194,17 @@ body {
border-radius
:
3px
;
border-radius
:
3px
;
}
}
/* --- */
/* --- */
.vm-details-remove-port
:hover
{
text-decoration
:
none
;
}
/* arrow in port add table */
#ipv4
tbody
td
:nth-child
(
2
),
#ipv6
tbody
td
:nth-child
(
2
)
{
width
:
60px
;
}
/* port add buttons */
.vm-details-network-port-add
.input-group-addon
,
.vm-details-network-port-add
.input-group-btn
{
width
:
inherit
;
}
circle/dashboard/static/dashboard/vm-details.js
View file @
651a6105
...
@@ -75,8 +75,39 @@ $(function() {
...
@@ -75,8 +75,39 @@ $(function() {
});
});
return
false
;
return
false
;
});
});
/* remove port */
$
(
'.vm-details-remove-port'
).
click
(
function
()
{
addModalConfirmation
(
removePort
,
{
'url'
:
$
(
this
).
prop
(
"href"
),
'data'
:
[],
'rule'
:
$
(
this
).
data
(
"rule"
)
});
return
false
;
});
});
});
function
removePort
(
data
)
{
$
.
ajax
({
type
:
'POST'
,
url
:
data
[
'url'
],
headers
:
{
"X-CSRFToken"
:
getCookie
(
'csrftoken'
)},
success
:
function
(
re
,
textStatus
,
xhr
)
{
$
(
"a[data-rule="
+
data
[
'rule'
]
+
"]"
).
each
(
function
()
{
$
(
this
).
closest
(
"tr"
).
fadeOut
(
500
,
function
()
{
$
(
this
).
remove
();
});
});
addMessage
(
re
[
'message'
],
"success"
);
},
error
:
function
(
xhr
,
textStatus
,
error
)
{
}
});
}
function
checkNewActivity
()
{
function
checkNewActivity
()
{
var
latest
=
$
(
'.activity:first'
).
data
(
'activity-id'
);
var
latest
=
$
(
'.activity:first'
).
data
(
'activity-id'
);
var
latest_sub
=
$
(
'div[data-activity-id="'
+
latest
+
'"] .sub-timeline .sub-activity:first'
).
data
(
'activity-id'
);
var
latest_sub
=
$
(
'div[data-activity-id="'
+
latest
+
'"] .sub-timeline .sub-activity:first'
).
data
(
'activity-id'
);
...
...
circle/dashboard/templates/dashboard/confirm/ajax-delete.html
View file @
651a6105
...
@@ -3,9 +3,13 @@
...
@@ -3,9 +3,13 @@
<div
class=
"modal-dialog"
>
<div
class=
"modal-dialog"
>
<div
class=
"modal-content"
>
<div
class=
"modal-content"
>
<div
class=
"modal-body"
>
<div
class=
"modal-body"
>
{% if text %}
{{ text }}
{% else %}
{%blocktrans with object=object%}
{%blocktrans with object=object%}
Are you sure you want to delete
<strong>
{{ object }}
</strong>
?
Are you sure you want to delete
<strong>
{{ object }}
</strong>
?
{%endblocktrans%}
{%endblocktrans%}
{% endif %}
<br
/>
<br
/>
<div
class=
"pull-right"
style=
"margin-top: 15px;"
>
<div
class=
"pull-right"
style=
"margin-top: 15px;"
>
<button
type=
"button"
class=
"btn btn-default"
data-dismiss=
"modal"
>
Cancel
</button>
<button
type=
"button"
class=
"btn btn-default"
data-dismiss=
"modal"
>
Cancel
</button>
...
...
circle/dashboard/templates/dashboard/confirm/base-delete.html
View file @
651a6105
...
@@ -6,13 +6,21 @@
...
@@ -6,13 +6,21 @@
<div
class=
"panel panel-default"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel-heading"
>
<div
class=
"panel-heading"
>
<h3
class=
"no-margin"
>
<h3
class=
"no-margin"
>
Delete confirmation
{% if title %}
{{ title }}
{% else %}
Delete confirmation
{% endif %}
</h3>
</h3>
</div>
</div>
<div
class=
"panel-body"
>
<div
class=
"panel-body"
>
{%blocktrans with object=object%}
{% if text %}
Are you sure you want to delete
<strong>
{{ object }}
</strong>
?
{{ text }}
{%endblocktrans%}
{% else %}
{%blocktrans with object=object%}
Are you sure you want to delete
<strong>
{{ object }}
</strong>
?
{%endblocktrans%}
{% endif %}
<div
class=
"pull-right"
>
<div
class=
"pull-right"
>
<form
action=
""
method=
"POST"
>
<form
action=
""
method=
"POST"
>
{% csrf_token %}
{% csrf_token %}
...
...
circle/dashboard/templates/dashboard/vm-detail-network-port-add.html
View file @
651a6105
<tfoot>
{% load i18n %}
<tr>
<div
class=
"vm-details-network-port-add pull-right"
>
<td
style=
"vertical-align: middle;"
>
<form
action=
""
method=
"POST"
>
<i
class=
"icon-plus"
></i>
<i
class=
"icon-long-arrow-right"
></i>
{% csrf_token %}
</td>
<input
type=
"hidden"
name=
"host_pk"
value=
"{{ i.host.pk }}"
/>
<td
colspan=
"2"
>
<div
class=
"input-group input-group-sm"
>
<div
class=
"input-group input-group-sm"
>
<span
class=
"input-group-addon"
>
<input
type=
"text"
class=
"form-control"
size=
"5"
/>
<i
class=
"icon-plus"
></i>
<i
class=
"icon-long-arrow-right"
></i>
<span
class=
"input-group-addon"
>
/
</span>
</span>
<select
class=
"form-control"
><option>
tcp
</option><option>
udp
</option></select>
<input
type=
"text"
class=
"form-control"
size=
"5"
style=
"width: 80px;"
name=
"port"
/>
</div>
<span
class=
"input-group-addon"
>
/
</span>
</td>
<select
class=
"form-control"
name=
"proto"
style=
"width: 70px;"
><option>
tcp
</option><option>
udp
</option></select>
<td>
<div
class=
"input-group-btn"
>
<button
type=
"submit"
class=
"btn btn-success btn-sm"
>
Add
</button>
<button
type=
"submit"
class=
"btn btn-success btn-sm"
>
{% trans "Add" %}
</button>
</td>
</div>
</tr>
</div>
</tfoot>
</form>
</div>
circle/dashboard/templates/dashboard/vm-detail-network.html
View file @
651a6105
...
@@ -44,31 +44,27 @@ Interfaces</h2>
...
@@ -44,31 +44,27 @@ Interfaces</h2>
</th></tr>
</th></tr>
</thead>
</thead>
<tbody>
<tbody>
<!-- inline td width shall be replaced -->
{% for l in i.host.list_ports %}
{% for l in i.host.list_ports %}
{% if l.ipv4 %}
{% if l.ipv4 %}
<tr>
<tr>
<td>
<td>
{{ l.ipv4.host }}:{{ l.ipv4.port }}
{{ l.ipv4.host }}:{{ l.ipv4.port }}
</td>
</td>
<td
style=
"width: 61px;"
><i
class=
"icon-long-arrow-right"
></i></td>
<td><i
class=
"icon-long-arrow-right"
></i></td>
<td
style=
"width: 111px;"
>
<td>
{{ l.private }}/{{ l.proto }}
{{ l.private }}/{{ l.proto }}
</td>
</td>
<td>
<td>
<a
href=
"
#"
class=
"btn btn-link btn-xs
"
title=
"{% trans "
Remove
"
%}"
><i
class=
"icon-remove"
><span
class=
"sr-only"
>
{% trans "Remove" %}
</span></i></a>
<a
href=
"
{% url "
dashboard
.
views
.
remove-port
"
pk=
instance.pk
rule=
l.ipv4.pk
%}"
class=
"btn btn-link btn-xs vm-details-remove-port"
data-rule=
"{{ l.ipv4.pk }}
"
title=
"{% trans "
Remove
"
%}"
><i
class=
"icon-remove"
><span
class=
"sr-only"
>
{% trans "Remove" %}
</span></i></a>
</td>
</td>
</tr>
</tr>
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
<tr><td>
vm.ik.bme.hu:22620
</td><td><i
class=
"icon-long-arrow-right"
></i></td><td><abbr
title=
"ssh"
>
22
</abbr>
/tcp
</td><td><a
href=
"#"
class=
"btn btn-link btn-xs"
title=
"remove"
><i
class=
"icon-remove"
><span
class=
"sr-only"
>
{% trans "remove" %}
</span></i></a></td></tr>
<tr><td>
vm.ik.bme.hu:22620
</td><td><i
class=
"icon-long-arrow-right"
></i></td><td>
12344/tcp
</td><td><a
href=
"#"
class=
"btn btn-link btn-xs"
title=
"remove"
><i
class=
"icon-remove"
><span
class=
"sr-only"
>
{% trans "remove" %}
</span></i></a></td></tr>
<tr><td>
vm.ik.bme.hu:22620
</td><td><i
class=
"icon-long-arrow-right"
></i></td><td><abbr
title=
"http-alt"
>
8080
</abbr>
/tcp
</td><td><a
href=
"#"
class=
"btn btn-link btn-xs"
title=
"remove"
><i
class=
"icon-remove"
><span
class=
"sr-only"
>
{% trans "remove" %}
</span></i></a></td></tr>
</tbody>
</tbody>
{% include "dashboard/vm-detail-network-port-add.html" %}
</table>
</table>
</div>
<!-- /ipv4 -->
</div>
<!-- /ipv4 -->
<div
class=
"tab-pane"
id=
"ipv6"
>
<div
class=
"tab-pane"
id=
"ipv6"
>
{% if i.host.ipv6 %}
<table
class=
"table table-striped rule-table"
>
<table
class=
"table table-striped rule-table"
>
<thead>
<thead>
<tr><th>
<tr><th>
...
@@ -80,30 +76,29 @@ Interfaces</h2>
...
@@ -80,30 +76,29 @@ Interfaces</h2>
</th></tr>
</th></tr>
</thead>
</thead>
<tbody>
<tbody>
<!-- inline td width TODO not do it -->
{% for l in i.host.list_ports %}
{% for l in i.host.list_ports %}
{% if l.ipv6 %}
{% if l.ipv6 %}
<tr>
<tr>
<td>
<td>
{{ l.ipv6.host }}:{{ l.ipv6.port }}
{{ l.ipv6.host }}:{{ l.ipv6.port }}
</td>
</td>
<td
style=
"width: 61px;"
><i
class=
"icon-long-arrow-right"
></i></td>
<td><i
class=
"icon-long-arrow-right"
></i></td>
<td
style=
"width: 111px;"
>
<td>
{{ l.private }}/{{ l.proto }}
{{ l.private }}/{{ l.proto }}
</td>
</td>
<td>
<td>
<a
href=
"
#"
class=
"btn btn-link btn-xs
"
title=
"{% trans "
Remove
"
%}"
><i
class=
"icon-remove"
><span
class=
"sr-only"
>
{% trans "Remove" %}
</span></i></a>
<a
href=
"
{% url "
dashboard
.
views
.
remove-port
"
pk=
instance.pk
rule=
l.ipv4.pk
%}"
class=
"btn btn-link btn-xs vm-details-remove-port"
data-rule=
"{{ l.ipv6.pk }}
"
title=
"{% trans "
Remove
"
%}"
><i
class=
"icon-remove"
><span
class=
"sr-only"
>
{% trans "Remove" %}
</span></i></a>
</td>
</td>
</tr>
</tr>
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
<tr><td>
550.vm.ik.bme.hu:22
</td><td><i
class=
"icon-long-arrow-right"
></i></td><td><abbr
title=
"ssh"
>
22
</abbr>
/tcp
</td><td><a
href=
"#"
class=
"btn btn-link btn-xs"
title=
"remove"
><i
class=
"icon-remove"
><span
class=
"sr-only"
>
{% trans "remove" %}
</span></i></a></td></tr>
<tr><td>
550.vm.ik.bme.hu:12344
</td><td><i
class=
"icon-long-arrow-right"
></i></td><td>
12344/tcp
</td><td><a
href=
"#"
class=
"btn btn-link btn-xs"
title=
"remove"
><i
class=
"icon-remove"
><span
class=
"sr-only"
>
{% trans "remove" %}
</span></i></a></td></tr>
<tr><td>
550.vm.ik.bme.hu:8080
</td><td><i
class=
"icon-long-arrow-right"
></i></td><td><abbr
title=
"http-alt"
>
8080
</abbr>
/tcp
</td><td><a
href=
"#"
class=
"btn btn-link btn-xs"
title=
"remove"
><i
class=
"icon-remove"
><span
class=
"sr-only"
>
{% trans "remove" %}
</span></i></a></td></tr>
</tbody>
</tbody>
{% include "dashboard/vm-detail-network-port-add.html" %}
</table>
</table>
</div>
{% else %}
<h4>
{% trans "This VM doesn't have an IPv6 address!" %}
</h4>
{% endif %}
</div>
<!-- /ipv6 -->
{% include "dashboard/vm-detail-network-port-add.html" %}
</div>
</div>
</div>
</div>
</div>
</div>
...
...
circle/dashboard/urls.py
View file @
651a6105
...
@@ -3,7 +3,7 @@ from django.conf.urls import patterns, url
...
@@ -3,7 +3,7 @@ from django.conf.urls import patterns, url
from
vm.models
import
Instance
from
vm.models
import
Instance
from
.views
import
(
from
.views
import
(
IndexView
,
VmDetailView
,
VmList
,
VmCreate
,
TemplateDetail
,
AclUpdateView
,
IndexView
,
VmDetailView
,
VmList
,
VmCreate
,
TemplateDetail
,
AclUpdateView
,
VmDelete
,
VmMassDelete
,
vm_activity
,
NodeList
,
NodeDetailView
,
VmDelete
,
VmMassDelete
,
vm_activity
,
NodeList
,
NodeDetailView
,
PortDelete
,
TransferOwnershipView
,
TransferOwnershipConfirmView
TransferOwnershipView
,
TransferOwnershipConfirmView
)
)
...
@@ -12,6 +12,8 @@ urlpatterns = patterns(
...
@@ -12,6 +12,8 @@ urlpatterns = patterns(
url
(
r'^$'
,
IndexView
.
as_view
(),
name
=
"dashboard.index"
),
url
(
r'^$'
,
IndexView
.
as_view
(),
name
=
"dashboard.index"
),
url
(
r'^template/(?P<pk>\d+)/$'
,
TemplateDetail
.
as_view
(),
url
(
r'^template/(?P<pk>\d+)/$'
,
TemplateDetail
.
as_view
(),
name
=
'dashboard.views.template-detail'
),
name
=
'dashboard.views.template-detail'
),
url
(
r'^vm/(?P<pk>\d+)/remove_port/(?P<rule>\d+)/$'
,
PortDelete
.
as_view
(),
name
=
'dashboard.views.remove-port'
),
url
(
r'^vm/(?P<pk>\d+)/$'
,
VmDetailView
.
as_view
(),
url
(
r'^vm/(?P<pk>\d+)/$'
,
VmDetailView
.
as_view
(),
name
=
'dashboard.views.detail'
),
name
=
'dashboard.views.detail'
),
url
(
r'^vm/(?P<pk>\d+)/acl/$'
,
AclUpdateView
.
as_view
(
model
=
Instance
),
url
(
r'^vm/(?P<pk>\d+)/acl/$'
,
AclUpdateView
.
as_view
(
model
=
Instance
),
...
...
circle/dashboard/views.py
View file @
651a6105
...
@@ -22,7 +22,7 @@ from braces.views import LoginRequiredMixin
...
@@ -22,7 +22,7 @@ from braces.views import LoginRequiredMixin
from
.tables
import
(
VmListTable
,
NodeListTable
)
from
.tables
import
(
VmListTable
,
NodeListTable
)
from
vm.models
import
(
Instance
,
InstanceTemplate
,
InterfaceTemplate
,
from
vm.models
import
(
Instance
,
InstanceTemplate
,
InterfaceTemplate
,
InstanceActivity
,
Node
,
instance_activity
)
InstanceActivity
,
Node
,
instance_activity
)
from
firewall.models
import
Vlan
from
firewall.models
import
Vlan
,
Host
,
Rule
from
storage.models
import
Disk
from
storage.models
import
Disk
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
...
@@ -120,6 +120,9 @@ class VmDetailView(CheckedDetailView):
...
@@ -120,6 +120,9 @@ class VmDetailView(CheckedDetailView):
if
request
.
POST
.
get
(
"to_remove"
)
is
not
None
:
if
request
.
POST
.
get
(
"to_remove"
)
is
not
None
:
return
self
.
__remove_tag
(
request
)
return
self
.
__remove_tag
(
request
)
if
request
.
POST
.
get
(
"port"
)
is
not
None
:
return
self
.
__add_port
(
request
)
def
__set_resources
(
self
,
request
):
def
__set_resources
(
self
,
request
):
self
.
object
=
self
.
get_object
()
self
.
object
=
self
.
get_object
()
if
not
self
.
object
.
has_level
(
request
.
user
,
'owner'
):
if
not
self
.
object
.
has_level
(
request
.
user
,
'owner'
):
...
@@ -201,6 +204,31 @@ class VmDetailView(CheckedDetailView):
...
@@ -201,6 +204,31 @@ class VmDetailView(CheckedDetailView):
content_type
=
"application=json"
content_type
=
"application=json"
)
)
def
__add_port
(
self
,
request
):
object
=
self
.
get_object
()
if
not
object
.
has_level
(
request
.
user
,
'owner'
):
raise
PermissionDenied
()
port
=
request
.
POST
.
get
(
"port"
)
proto
=
request
.
POST
.
get
(
"proto"
)
try
:
error
=
None
host
=
Host
.
objects
.
get
(
pk
=
request
.
POST
.
get
(
"host_pk"
))
host
.
add_port
(
proto
,
private
=
port
)
except
Host
.
DoesNotExist
:
error
=
_
(
"Host not found!"
)
except
Exception
,
e
:
error
=
u', '
.
join
(
e
.
messages
)
if
request
.
is_ajax
():
pass
else
:
if
error
:
messages
.
error
(
request
,
error
)
return
redirect
(
reverse_lazy
(
"dashboard.views.detail"
,
kwargs
=
{
'pk'
:
self
.
get_object
()
.
pk
}))
class
NodeDetailView
(
DetailView
):
class
NodeDetailView
(
DetailView
):
template_name
=
"dashboard/node-detail.html"
template_name
=
"dashboard/node-detail.html"
...
@@ -389,6 +417,7 @@ class VmDelete(DeleteView):
...
@@ -389,6 +417,7 @@ class VmDelete(DeleteView):
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
# this is redundant now, but if we wanna add more to print
# this is redundant now, but if we wanna add more to print
# we'll need this
# we'll need this
print
kwargs
context
=
super
(
VmDelete
,
self
)
.
get_context_data
(
**
kwargs
)
context
=
super
(
VmDelete
,
self
)
.
get_context_data
(
**
kwargs
)
return
context
return
context
...
@@ -421,6 +450,52 @@ class VmDelete(DeleteView):
...
@@ -421,6 +450,52 @@ class VmDelete(DeleteView):
return
reverse_lazy
(
'dashboard.index'
)
return
reverse_lazy
(
'dashboard.index'
)
class
PortDelete
(
DeleteView
):
model
=
Rule
pk_url_kwarg
=
'rule'
def
get_template_names
(
self
):
if
self
.
request
.
is_ajax
():
return
[
'dashboard/confirm/ajax-delete.html'
]
else
:
return
[
'dashboard/confirm/base-delete.html'
]
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
PortDelete
,
self
)
.
get_context_data
(
**
kwargs
)
rule
=
kwargs
.
get
(
'object'
)
instance
=
rule
.
host
.
interface_set
.
get
()
.
instance
context
[
'title'
]
=
_
(
"Port delete confirmation"
)
context
[
'text'
]
=
_
(
"Are you sure you want to close
%(port)
d/"
"
%(proto)
s on
%(vm)
s?"
%
{
'port'
:
rule
.
dport
,
'proto'
:
rule
.
proto
,
'vm'
:
instance
})
return
context
def
delete
(
self
,
request
,
*
args
,
**
kwargs
):
rule
=
Rule
.
objects
.
get
(
pk
=
kwargs
.
get
(
"rule"
))
instance
=
rule
.
host
.
interface_set
.
get
()
.
instance
if
not
instance
.
has_level
(
request
.
user
,
'owner'
):
raise
PermissionDenied
()
super
(
PortDelete
,
self
)
.
delete
(
request
,
*
args
,
**
kwargs
)
success_url
=
self
.
get_success_url
()
success_message
=
_
(
"Port successfully removed!"
)
if
request
.
is_ajax
():
return
HttpResponse
(
json
.
dumps
({
'message'
:
success_message
}),
content_type
=
"application/json"
,
)
else
:
messages
.
success
(
request
,
success_message
)
return
HttpResponseRedirect
(
"
%
s#network"
%
success_url
)
def
get_success_url
(
self
):
return
reverse_lazy
(
'dashboard.views.detail'
,
kwargs
=
{
'pk'
:
self
.
kwargs
.
get
(
"pk"
)})
class
VmMassDelete
(
View
):
class
VmMassDelete
(
View
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
vms
=
request
.
GET
.
getlist
(
'v[]'
)
vms
=
request
.
GET
.
getlist
(
'v[]'
)
...
...
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