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
fda9c192
authored
Mar 03, 2018
by
Szabolcs Gelencser
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implement network create, details
parent
327e7892
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
72 additions
and
149 deletions
+72
-149
.idea/workspace.xml
+0
-0
circle/circle/db.sqlite3
+0
-0
circle/dashboard/templates/dashboard/index-vxlans.html
+1
-1
circle/dashboard/views/index.py
+1
-1
circle/network/forms.py
+8
-18
circle/network/models.py
+5
-1
circle/network/templates/network/vxlan-create.html
+9
-7
circle/network/templates/network/vxlan-edit.html
+3
-8
circle/network/urls.py
+3
-2
circle/network/views.py
+41
-110
circle/openstack_api/nova.py
+1
-1
No files found.
.idea/workspace.xml
View file @
fda9c192
This diff is collapsed.
Click to expand it.
circle/circle/db.sqlite3
View file @
fda9c192
No preview for this file type
circle/dashboard/templates/dashboard/index-vxlans.html
View file @
fda9c192
...
...
@@ -13,7 +13,7 @@
<div
class=
"list-group"
id=
"vxlan-list-view"
>
<div
id=
"dashboard-vxlan-list"
>
{% for vxlan in vxlans %}
<a
href=
"{% url "
network
.
vxlan
"
vni=
vxlan.vni
%}"
class=
"list-group-item
<a
href=
"{% url "
network
.
vxlan
"
pk=
vxlan.id
%}"
class=
"list-group-item
{% if forloop.last and vxlan|length < 5 %} list-group-item-last{% endif %}"
>
<span
class=
"index-vxlan-list-name"
>
<i
class=
"fa fa-sitemap"
></i>
{{ vxlan.name }}
...
...
circle/dashboard/views/index.py
View file @
fda9c192
...
...
@@ -106,7 +106,7 @@ class IndexView(LoginRequiredMixin, TemplateView):
'operator'
,
user
,
disregard_superuser
=
True
)
.
all
()[:
5
]
# vxlan
#context['vxlans'] = Instance
.list_from_os(self.request)[:5]
context
[
'vxlans'
]
=
Vxlan
.
list_from_os
(
self
.
request
)[:
5
]
# toplist
if
settings
.
STORE_URL
:
...
...
circle/network/forms.py
View file @
fda9c192
...
...
@@ -16,6 +16,7 @@
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from
django.forms
import
ModelForm
,
widgets
from
django
import
forms
from
django.core.urlresolvers
import
reverse_lazy
from
django.utils.translation
import
ugettext_lazy
as
_
...
...
@@ -28,6 +29,7 @@ from firewall.models import (
SwitchPort
,
Firewall
)
from
network.models
import
Vxlan
from
openstack_api.neutron
import
Network
class
LinkButton
(
BaseInput
):
...
...
@@ -372,21 +374,9 @@ class VxlanSuperUserForm(ModelForm):
)
)
class
VxlanForm
(
ModelForm
):
helper
=
FormHelper
()
helper
.
layout
=
Layout
(
Div
(
Fieldset
(
''
,
'name'
,
'description'
,
'comment'
,
Field
(
'vni'
,
type
=
'hidden'
),
)
),
FormActions
(
Submit
(
'submit'
,
_
(
'Save'
)),
LinkButton
(
'back'
,
_
(
'Back'
),
reverse_lazy
(
'network.vxlan-list'
))
)
)
class
VxlanForm
(
forms
.
Form
):
name
=
forms
.
CharField
(
widget
=
forms
.
TextInput
(
attrs
=
{
'class'
:
"form-control"
,
'required'
:
""
,
}))
circle/network/models.py
View file @
fda9c192
...
...
@@ -14,7 +14,7 @@
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
import
openstack_api
from
django.db
import
models
from
django.core.validators
import
MinValueValidator
,
MaxValueValidator
from
django.core.urlresolvers
import
reverse
...
...
@@ -68,6 +68,10 @@ class Vxlan(models.Model):
class
Meta
:
app_label
=
'network'
@classmethod
def
list_from_os
(
cls
,
request
):
return
openstack_api
.
neutron
.
network_list_for_tenant
(
request
,
request
.
user
.
tenant_id
)
def
__unicode__
(
self
):
return
self
.
name
...
...
circle/network/templates/network/vxlan-create.html
View file @
fda9c192
...
...
@@ -5,18 +5,20 @@
{% load staticfiles %}
{% load crispy_forms_tags %}
{% block title-page %}{% trans "Create" %} | {% trans "
vxlan
" %}{% endblock %}
{% block title-page %}{% trans "Create" %} | {% trans "
network
" %}{% endblock %}
{% block content %}
<div
class=
"page-header"
>
<h2>
{% trans "Create a new
vxlan
" %}
</h2>
<h2>
{% trans "Create a new
network
" %}
</h2>
</div>
<div
class=
"row"
>
<div
class=
"col-sm-8"
>
{% crispy form %}
</div>
<div
class=
"col-sm-4"
>
</div>
<form
method=
"POST"
"
>
{% csrf_token %}
{{ form.name|as_crispy_field }}
<button
class=
"btn btn-success pull-right text-right"
type=
"submit"
>
<i
class=
"fa fa-plus"
></i>
{% trans "Create" %}
</button>
</form>
</div>
{% endblock %}
circle/network/templates/network/vxlan-edit.html
View file @
fda9c192
...
...
@@ -9,8 +9,8 @@
{% block content %}
<div
class=
"page-header"
>
<a
href=
"{% url "
network
.
vxlan-delete
"
vni=
vxlan.vni
%}"
class=
"btn btn-danger pull-right"
><i
class=
"fa fa-times-circle"
></i>
{% trans "Delete this vxlan
" %}
</a>
<h2>
{{ form.name.value }}
<small>
{% trans "details of
vxlan
" %}
</small></h2>
<a
href=
"{% url "
network
.
vxlan-delete
"
pk=
network.id
%}"
class=
"btn btn-danger pull-right"
><i
class=
"fa fa-times-circle"
></i>
{% trans "Delete this network
" %}
</a>
<h2>
{{ form.name.value }}
<small>
{% trans "details of
network
" %}
</small></h2>
</div>
<div
class=
"row"
>
...
...
@@ -21,12 +21,7 @@
<div
class=
"page-header"
>
<h3>
{% trans "Connected virtual machines" %}
</h3>
</div>
{% render_table vm_list %}
<div
class=
"page-header"
>
<h3>
{% trans "Manage access" %}
</h3>
</div>
{% include "dashboard/_manage_access.html" with table_id="vxlan-access-table" %}
{# {% render_table vm_list %}#}
</div>
</div>
{% endblock %}
circle/network/urls.py
View file @
fda9c192
...
...
@@ -129,10 +129,11 @@ urlpatterns = [
# vxlan
url
(
'^vxlans/$'
,
VxlanList
.
as_view
(),
name
=
'network.vxlan-list'
),
url
(
'^vxlans/create$'
,
VxlanCreate
.
as_view
(),
name
=
'network.vxlan-create'
),
url
(
'^vxlans/(?P<vni>
\
d+)/$'
,
VxlanDetail
.
as_view
(),
name
=
'network.vxlan'
),
url
(
'^vxlans/(?P<pk>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/$'
,
VxlanDetail
.
as_view
(),
name
=
'network.vxlan'
),
url
(
'^vxlans/(?P<pk>
\
d+)/acl/$'
,
VxlanAclUpdateView
.
as_view
(),
name
=
'network.vxlan-acl'
),
url
(
'^vxlans/delete/(?P<
vni>
\
d+
)/$'
,
VxlanDelete
.
as_view
(),
url
(
'^vxlans/delete/(?P<
pk>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
)/$'
,
VxlanDelete
.
as_view
(),
name
=
"network.vxlan-delete"
),
# editor
...
...
circle/network/views.py
View file @
fda9c192
...
...
@@ -20,10 +20,11 @@ import random
import
json
from
collections
import
OrderedDict
import
openstack_api
from
netaddr
import
IPNetwork
from
django.views.generic
import
(
TemplateView
,
UpdateView
,
DeleteView
,
CreateView
,
)
DetailView
)
from
django.core.exceptions
import
(
ValidationError
,
PermissionDenied
,
ImproperlyConfigured
)
...
...
@@ -40,6 +41,8 @@ from firewall.models import (
SwitchPort
,
EthernetDevice
,
Firewall
)
from
network.models
import
Vxlan
,
EditorElement
from
numpy.distutils.from_template
import
template_name_re
from
openstack_api.neutron
import
Network
from
vm.models
import
Interface
,
Instance
from
common.views
import
CreateLimitedResourceMixin
from
.tables
import
(
...
...
@@ -50,9 +53,7 @@ from .tables import (
)
from
.forms
import
(
HostForm
,
VlanForm
,
DomainForm
,
GroupForm
,
RecordForm
,
BlacklistItemForm
,
RuleForm
,
VlanGroupForm
,
SwitchPortForm
,
FirewallForm
,
VxlanForm
,
VxlanSuperUserForm
,
)
RuleForm
,
VlanGroupForm
,
SwitchPortForm
,
FirewallForm
,
VxlanForm
)
from
django.contrib
import
messages
from
django.contrib.messages.views
import
SuccessMessageMixin
...
...
@@ -61,7 +62,7 @@ from django.utils.translation import ugettext_lazy as _
from
braces.views
import
LoginRequiredMixin
,
SuperuserRequiredMixin
from
operator
import
itemgetter
from
itertools
import
chain
from
dashboard.views
import
AclUpdateView
from
dashboard.views
import
AclUpdateView
,
FormView
from
dashboard.forms
import
AclUserOrGroupAddForm
try
:
...
...
@@ -94,14 +95,6 @@ class MagicMixin(object):
else
:
return
super
(
MagicMixin
,
self
)
.
get
(
*
args
,
**
kwargs
)
class
InitialOwnerMixin
(
FormMixin
):
def
get_initial
(
self
):
initial
=
super
(
InitialOwnerMixin
,
self
)
.
get_initial
()
initial
[
'owner'
]
=
self
.
request
.
user
return
initial
class
IndexView
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
TemplateView
):
template_name
=
"network/index.html"
...
...
@@ -225,7 +218,7 @@ class DomainDetail(LoginRequiredMixin, SuperuserRequiredMixin,
class
DomainCreate
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
SuccessMessageMixin
,
InitialOwnerMixin
,
CreateView
):
SuccessMessageMixin
,
CreateView
):
model
=
Domain
template_name
=
"network/domain-create.html"
form_class
=
DomainForm
...
...
@@ -356,7 +349,7 @@ class GroupList(LoginRequiredMixin, SuperuserRequiredMixin, SingleTableView):
class
GroupCreate
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
SuccessMessageMixin
,
InitialOwnerMixin
,
CreateView
):
SuccessMessageMixin
,
CreateView
):
model
=
Group
template_name
=
"network/group-create.html"
form_class
=
GroupForm
...
...
@@ -621,7 +614,7 @@ class RecordDetail(LoginRequiredMixin, SuperuserRequiredMixin,
class
RecordCreate
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
SuccessMessageMixin
,
InitialOwnerMixin
,
CreateView
):
SuccessMessageMixin
,
CreateView
):
model
=
Record
template_name
=
"network/record-create.html"
form_class
=
RecordForm
...
...
@@ -708,7 +701,7 @@ class RuleDetail(LoginRequiredMixin, SuperuserRequiredMixin,
class
RuleCreate
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
SuccessMessageMixin
,
InitialOwnerMixin
,
CreateView
):
SuccessMessageMixin
,
CreateView
):
model
=
Rule
template_name
=
"network/rule-create.html"
form_class
=
RuleForm
...
...
@@ -743,6 +736,22 @@ class SwitchPortList(LoginRequiredMixin, SuperuserRequiredMixin,
table_pagination
=
False
class
RuleCreate
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
SuccessMessageMixin
,
CreateView
):
model
=
Rule
template_name
=
"network/rule-create.html"
form_class
=
RuleForm
success_message
=
_
(
u'Successfully created rule.'
)
def
get_initial
(
self
):
initial
=
super
(
RuleCreate
,
self
)
.
get_initial
()
initial
.
update
({
'host'
:
self
.
request
.
GET
.
get
(
'host'
),
'hostgroup'
:
self
.
request
.
GET
.
get
(
'hostgroup'
)
})
return
initial
class
SwitchPortDetail
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
SuccessMessageMixin
,
UpdateView
):
model
=
SwitchPort
...
...
@@ -829,7 +838,7 @@ class VlanDetail(VlanMagicMixin, LoginRequiredMixin, SuperuserRequiredMixin,
class
VlanCreate
(
VlanMagicMixin
,
LoginRequiredMixin
,
SuperuserRequiredMixin
,
SuccessMessageMixin
,
InitialOwnerMixin
,
CreateView
):
SuccessMessageMixin
,
CreateView
):
model
=
Vlan
template_name
=
"network/vlan-create.html"
form_class
=
VlanForm
...
...
@@ -909,7 +918,7 @@ class VlanGroupDetail(LoginRequiredMixin, SuperuserRequiredMixin,
class
VlanGroupCreate
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
SuccessMessageMixin
,
InitialOwnerMixin
,
CreateView
):
SuccessMessageMixin
,
CreateView
):
model
=
VlanGroup
template_name
=
"network/vlan-group-create.html"
form_class
=
VlanGroupForm
...
...
@@ -963,107 +972,29 @@ class VxlanAclUpdateView(AclUpdateView):
model
=
Vxlan
class
VxlanDetail
(
LoginRequiredMixin
,
SuccessMessageMixin
,
UpdateView
):
#TODO: check user
model
=
Vxlan
slug_field
=
'vni'
slug_url_kwarg
=
'vni'
class
VxlanDetail
(
LoginRequiredMixin
,
SuccessMessageMixin
,
DetailView
):
#TODO: check user
# model = Network
success_message
=
_
(
u'Succesfully modified vlan
%(name)
s.'
)
success_url
=
reverse_lazy
(
'network.vxlan-list'
)
template_name
=
'network/vxlan-edit.html'
context_object_name
=
'network'
def
get_template_names
(
self
):
if
self
.
request
.
user
.
is_superuser
:
return
[
"network/vxlan-superuser-edit.html"
]
else
:
return
[
"network/vxlan-edit.html"
]
def
get_form_class
(
self
,
is_post
=
False
):
if
self
.
request
.
user
.
is_superuser
:
return
VxlanSuperUserForm
return
VxlanForm
def
get_object
(
self
,
queryset
=
None
):
return
openstack_api
.
neutron
.
network_get
(
self
.
request
,
self
.
kwargs
[
'pk'
])
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
VxlanDetail
,
self
)
.
get_context_data
(
**
kwargs
)
context
[
'vm_list'
]
=
SmallVmTable
(
self
.
object
.
vm_interface
.
all
())
context
[
'acl'
]
=
AclUpdateView
.
get_acl_data
(
self
.
object
,
self
.
request
.
user
,
'network.vxlan-acl'
)
context
[
'aclform'
]
=
AclUserOrGroupAddForm
()
context
[
'vm_list'
]
=
()
#SmallVmTable(self.object.vm_interface.all())
context
[
'form'
]
=
VxlanForm
return
context
def
post
(
self
,
*
args
,
**
kwargs
):
if
not
self
.
object
.
has_level
(
self
.
request
.
user
,
'owner'
):
raise
PermissionDenied
()
return
super
(
VxlanDetail
,
self
)
.
post
(
*
args
,
**
kwargs
)
class
VxlanCreate
(
LoginRequiredMixin
,
SuccessMessageMixin
,
InitialOwnerMixin
,
CreateView
):
model
=
Vxlan
profile_attribute
=
'network_limit'
resource_name
=
_
(
'Virtual network'
)
success_message
=
_
(
u'Successfully created vxlan
%(name)
s.'
)
def
get_template_names
(
self
):
if
self
.
request
.
user
.
is_superuser
:
return
[
"network/vxlan-superuser-create.html"
]
else
:
return
[
"network/vxlan-create.html"
]
def
get_form_class
(
self
,
is_post
=
False
):
if
self
.
request
.
user
.
is_superuser
:
return
VxlanSuperUserForm
return
VxlanForm
def
get_initial
(
self
):
initial
=
super
(
VxlanCreate
,
self
)
.
get_initial
()
initial
[
'vni'
]
=
self
.
_generate_vni
()
return
initial
def
get_default_vlan
(
self
):
vlan
=
Vlan
.
objects
.
filter
(
name
=
settings
.
DEFAULT_USERNET_VLAN_NAME
)
.
first
()
if
vlan
is
None
:
msg
=
(
_
(
'Cannot find server vlan:
%
s'
)
%
settings
.
DEFAULT_USERNET_VLAN_NAME
)
if
self
.
request
.
user
.
is_superuser
:
messages
.
error
(
self
.
request
,
msg
)
logger
.
error
(
msg
)
raise
ImproperlyConfigured
()
return
vlan
class
VxlanCreate
(
LoginRequiredMixin
,
FormView
):
form_class
=
VxlanForm
template_name
=
'network/vxlan-create.html'
def
form_valid
(
self
,
form
):
obj
=
form
.
save
(
commit
=
False
)
obj
.
vlan
=
self
.
get_default_vlan
()
try
:
obj
.
full_clean
()
obj
.
save
()
obj
.
set_level
(
obj
.
owner
,
'owner'
)
self
.
object
=
obj
except
Exception
as
e
:
msg
=
_
(
'Unexpected error occured. '
'Please try again or contact administrator!'
)
messages
.
error
(
self
.
request
,
msg
)
logger
.
exception
(
e
)
return
redirect
(
self
.
get_success_url
())
def
form_invalid
(
self
,
form
):
# When multiple client get same VNI value
if
'vni'
in
form
.
errors
.
as_data
():
messages
.
error
(
self
.
request
,
_
(
'Cannot create virtual network.'
' Please try again.'
))
return
redirect
(
'network.vxlan-create'
)
return
super
(
VxlanCreate
,
self
)
.
form_invalid
(
form
)
def
_generate_vni
(
self
):
if
Vxlan
.
objects
.
count
()
==
settings
.
USERNET_MAX
:
msg
=
_
(
'Cannot find unused VNI value. '
'Please contact administrator!'
)
messages
.
error
(
self
.
request
,
msg
)
logger
.
error
(
msg
)
else
:
full_range
=
set
(
range
(
0
,
settings
.
USERNET_MAX
))
used_values
=
{
vni
[
0
]
for
vni
in
Vxlan
.
objects
.
values_list
(
'vni'
)}
free_values
=
full_range
-
used_values
return
random
.
choice
(
list
(
free_values
))
network_created
=
openstack_api
.
neutron
.
network_create
(
self
.
request
,
name
=
form
.
cleaned_data
[
'name'
])
return
redirect
(
reverse_lazy
(
'network.vxlan'
,
kwargs
=
{
'pk'
:
network_created
.
id
}))
class
VxlanDelete
(
LoginRequiredMixin
,
DeleteView
):
#TODO: check user
model
=
Vlan
...
...
circle/openstack_api/nova.py
View file @
fda9c192
...
...
@@ -508,7 +508,7 @@ def keypair_get(request, name):
def
server_create
(
request
,
name
,
image
,
flavor
,
key_name
=
None
,
user_data
=
None
,
security_groups
=
None
,
block_device_mapping
=
None
,
block_device_mapping_v2
=
None
,
nics
=
"
auto
"
,
block_device_mapping_v2
=
None
,
nics
=
"
none
"
,
availability_zone
=
None
,
instance_count
=
1
,
admin_pass
=
None
,
disk_config
=
None
,
config_drive
=
None
,
meta
=
None
,
scheduler_hints
=
None
,
description
=
None
):
...
...
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