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
53dbd80b
authored
Oct 04, 2017
by
Czémán Arnold
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'issue_494' into 'master'
Upgrade to Django 1.11 See merge request
!395
parents
4565cf03
df34da69
Pipeline
#549
passed with stage
in 0 seconds
Changes
44
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
44 changed files
with
399 additions
and
317 deletions
+399
-317
circle/acl/management/__init__.py
+10
-8
circle/acl/models.py
+1
-1
circle/circle/__init__.py
+3
-2
circle/circle/settings/base.py
+112
-105
circle/circle/settings/local.py
+4
-2
circle/circle/settings/selenium_test.py
+2
-1
circle/circle/settings/test.py
+6
-2
circle/circle/urls.py
+14
-17
circle/common/views.py
+2
-1
circle/dashboard/forms.py
+17
-14
circle/dashboard/management/commands/init.py
+16
-17
circle/dashboard/migrations/0006_auto_20170707_1909.py
+20
-0
circle/dashboard/models.py
+1
-1
circle/dashboard/static/dashboard/dashboard.js
+0
-7
circle/dashboard/static/dashboard/dashboard.less
+1
-1
circle/dashboard/templates/dashboard/_manage_access.html
+2
-2
circle/dashboard/templates/dashboard/group-detail.html
+4
-2
circle/dashboard/templates/dashboard/lease-edit.html
+2
-2
circle/dashboard/templates/django_tables2/table_no_page.html
+2
-3
circle/dashboard/tests/test_mockedviews.py
+4
-4
circle/dashboard/tests/test_templates.py
+5
-5
circle/dashboard/tests/test_views.py
+5
-5
circle/dashboard/urls.py
+23
-23
circle/dashboard/views/__init__.py
+1
-0
circle/dashboard/views/autocomplete.py
+32
-39
circle/dashboard/views/graph.py
+9
-0
circle/dashboard/views/index.py
+1
-2
circle/dashboard/views/node.py
+6
-3
circle/dashboard/views/store.py
+2
-4
circle/dashboard/views/user.py
+1
-1
circle/dashboard/views/vm.py
+3
-4
circle/firewall/admin.py
+1
-0
circle/firewall/fields.py
+28
-3
circle/firewall/fw.py
+3
-3
circle/firewall/migrations/0006_auto_20170707_1909.py
+26
-0
circle/firewall/tests/test_firewall.py
+1
-1
circle/network/urls.py
+3
-4
circle/request/forms.py
+1
-3
circle/request/urls.py
+3
-4
circle/vm/__init__.py
+1
-2
circle/vm/tests/test_models.py
+2
-2
requirements/base.txt
+14
-12
requirements/local.txt
+2
-2
requirements/test.txt
+3
-3
No files found.
circle/acl/management/__init__.py
View file @
53dbd80b
"""
Creates Levels for all installed apps that have levels.
"""
from
django.db.models
import
get_models
,
signals
from
django.db.models
import
signals
from
django.apps
import
apps
from
django.db
import
DEFAULT_DB_ALIAS
from
django.core.exceptions
import
ImproperlyConfigured
from
..models
import
Level
,
AclBase
def
create_levels
(
app
,
created_models
,
verbosity
,
db
=
DEFAULT_DB_ALIAS
,
def
create_levels
(
app
_config
,
verbosity
=
False
,
using
=
DEFAULT_DB_ALIAS
,
**
kwargs
):
"""Create and set the weights of the configured Levels.
Based on django.contrib.auth.management.__init__.create_permissions"""
# if not router.allow_migrate(
db
, auth_app.Permission):
# if not router.allow_migrate(
using
, auth_app.Permission):
# return
from
django.contrib.contenttypes.models
import
ContentType
app_models
=
[
k
for
k
in
get_models
(
app
)
if
AclBase
in
k
.
__bases__
]
app_models
=
[
k
for
k
in
apps
.
get_models
(
app_config
)
if
AclBase
in
k
.
__bases__
]
print
"Creating levels for models:
%
s."
%
", "
.
join
(
[
m
.
__name__
for
m
in
app_models
])
...
...
@@ -31,7 +33,7 @@ def create_levels(app, created_models, verbosity, db=DEFAULT_DB_ALIAS,
for
klass
in
app_models
:
# Force looking up the content types in the current database
# before creating foreign keys to them.
ctype1
=
ContentType
.
objects
.
db_manager
(
db
)
.
get_for_model
(
klass
)
ctype1
=
ContentType
.
objects
.
db_manager
(
using
)
.
get_for_model
(
klass
)
ctypes
.
add
(
ctype1
)
weight
=
0
try
:
...
...
@@ -46,7 +48,7 @@ def create_levels(app, created_models, verbosity, db=DEFAULT_DB_ALIAS,
# Find all the Levels that have a content_type for a model we're
# looking for. We don't need to check for codenames since we already have
# a list of the ones we're going to create.
all_levels
=
set
(
Level
.
objects
.
using
(
db
)
.
filter
(
all_levels
=
set
(
Level
.
objects
.
using
(
using
)
.
filter
(
content_type__in
=
ctypes
,
)
.
values_list
(
"content_type"
,
"codename"
...
...
@@ -57,7 +59,7 @@ def create_levels(app, created_models, verbosity, db=DEFAULT_DB_ALIAS,
for
ctype
,
(
codename
,
name
)
in
searched_levels
if
(
ctype
.
pk
,
codename
)
not
in
all_levels
]
Level
.
objects
.
using
(
db
)
.
bulk_create
(
levels
)
Level
.
objects
.
using
(
using
)
.
bulk_create
(
levels
)
if
verbosity
>=
2
:
print
(
"Adding levels [
%
s]."
%
", "
.
join
(
unicode
(
l
)
for
l
in
levels
))
print
(
"Searched: [
%
s]."
%
", "
.
join
(
...
...
@@ -70,5 +72,5 @@ def create_levels(app, created_models, verbosity, db=DEFAULT_DB_ALIAS,
content_type
=
ctype
)
.
update
(
weight
=
weight
)
signals
.
post_
syncdb
.
connect
(
signals
.
post_
migrate
.
connect
(
create_levels
,
dispatch_uid
=
"circle.acl.management.create_levels"
)
circle/acl/models.py
View file @
53dbd80b
...
...
@@ -18,7 +18,7 @@
import
logging
from
django.contrib.auth.models
import
User
,
Group
from
django.contrib.contenttypes.
generic
import
(
from
django.contrib.contenttypes.
fields
import
(
GenericForeignKey
,
GenericRelation
)
from
django.contrib.contenttypes.models
import
ContentType
...
...
circle/circle/__init__.py
View file @
53dbd80b
...
...
@@ -12,9 +12,10 @@ def update_permissions_after_migration(sender, **kwargs):
"""
from
django.conf
import
settings
from
django.
db.models
import
get_model
s
from
django.
apps
import
app
s
from
django.contrib.auth.management
import
create_permissions
create_permissions
(
sender
,
get_models
(),
2
if
settings
.
DEBUG
else
0
)
create_permissions
(
sender
,
apps
.
get_models
(),
2
if
settings
.
DEBUG
else
0
)
post_migrate
.
connect
(
update_permissions_after_migration
)
circle/circle/settings/base.py
View file @
53dbd80b
...
...
@@ -166,96 +166,95 @@ if exists(p):
STATICFILES_DIRS
.
append
(
p
)
STATICFILES_STORAGE
=
'pipeline.storage.PipelineCachedStorage'
PIPELINE_COMPILERS
=
(
'pipeline.compilers.less.LessCompiler'
,
)
PIPELINE_CSS_COMPRESSOR
=
'pipeline.compressors.yuglify.YuglifyCompressor'
# PIPELINE_JS_COMPRESSOR = 'pipeline.compressors.slimit.SlimItCompressor'
PIPELINE_JS_COMPRESSOR
=
None
PIPELINE_DISABLE_WRAPPER
=
True
PIPELINE_LESS_ARGUMENTS
=
u'--include-path={}'
.
format
(
':'
.
join
(
STATICFILES_DIRS
))
PIPELINE_CSS
=
{
"all"
:
{
"source_filenames"
:
(
"compile_bootstrap.less"
,
"bootstrap/dist/css/bootstrap-theme.css"
,
"fontawesome/css/font-awesome.css"
,
"jquery-simple-slider/css/simple-slider.css"
,
"intro.js/introjs.css"
,
"template.less"
,
"dashboard/dashboard.less"
,
"network/network.less"
,
"autocomplete_light/style.css"
,
),
"output_filename"
:
"all.css"
,
}
}
PIPELINE_JS
=
{
"all"
:
{
"source_filenames"
:
(
# "jquery/dist/jquery.js", # included separately
"bootbox/bootbox.js"
,
"bootstrap/dist/js/bootstrap.js"
,
"intro.js/intro.js"
,
"jquery-knob/dist/jquery.knob.min.js"
,
"jquery-simple-slider/js/simple-slider.js"
,
"favico.js/favico.js"
,
"datatables/media/js/jquery.dataTables.js"
,
"dashboard/dashboard.js"
,
"dashboard/activity.js"
,
"dashboard/group-details.js"
,
"dashboard/group-list.js"
,
"dashboard/js/stupidtable.min.js"
,
# no bower file
"dashboard/node-create.js"
,
"dashboard/node-details.js"
,
"dashboard/node-list.js"
,
"dashboard/profile.js"
,
"dashboard/store.js"
,
"dashboard/template-list.js"
,
"dashboard/vm-common.js"
,
"dashboard/vm-create.js"
,
"dashboard/vm-list.js"
,
"dashboard/help.js"
,
"js/host.js"
,
"js/network.js"
,
"js/switch-port.js"
,
"js/host-list.js"
,
"autocomplete_light/autocomplete.js"
,
"autocomplete_light/widget.js"
,
"autocomplete_light/addanother.js"
,
"autocomplete_light/text_widget.js"
,
"autocomplete_light/remote.js"
,
),
"output_filename"
:
"all.js"
,
},
"vm-detail"
:
{
"source_filenames"
:
(
"clipboard/dist/clipboard.min.js"
,
"dashboard/vm-details.js"
,
"no-vnc/include/util.js"
,
"no-vnc/include/webutil.js"
,
"no-vnc/include/base64.js"
,
"no-vnc/include/websock.js"
,
"no-vnc/include/des.js"
,
"no-vnc/include/keysym.js"
,
"no-vnc/include/keysymdef.js"
,
"no-vnc/include/keyboard.js"
,
"no-vnc/include/input.js"
,
"no-vnc/include/display.js"
,
"no-vnc/include/jsunzip.js"
,
"no-vnc/include/rfb.js"
,
"dashboard/vm-console.js"
,
"dashboard/vm-tour.js"
,
),
"output_filename"
:
"vm-detail.js"
,
PIPELINE
=
{
'COMPILERS'
:
(
'pipeline.compilers.less.LessCompiler'
,),
'LESS_ARGUMENTS'
:
u'--include-path={}'
.
format
(
':'
.
join
(
STATICFILES_DIRS
)),
'CSS_COMPRESSOR'
:
'pipeline.compressors.yuglify.YuglifyCompressor'
,
'JS_COMPRESSOR'
:
None
,
'DISABLE_WRAPPER'
:
True
,
'STYLESHEETS'
:
{
"all"
:
{
"source_filenames"
:
(
"compile_bootstrap.less"
,
"bootstrap/dist/css/bootstrap-theme.css"
,
"fontawesome/css/font-awesome.css"
,
"jquery-simple-slider/css/simple-slider.css"
,
"intro.js/introjs.css"
,
"template.less"
,
"dashboard/dashboard.less"
,
"network/network.less"
,
"autocomplete_light/vendor/select2/dist/css/select2.css"
,
"autocomplete_light/select2.css"
,
),
"output_filename"
:
"all.css"
,
}
},
"datastore"
:
{
"source_filenames"
:
(
"chart.js/dist/Chart.min.js"
,
"dashboard/datastore-details.js"
),
"output_filename"
:
"datastore.js"
,
'JAVASCRIPT'
:
{
"all"
:
{
"source_filenames"
:
(
# "jquery/dist/jquery.js", # included separately
"bootbox/bootbox.js"
,
"bootstrap/dist/js/bootstrap.js"
,
"intro.js/intro.js"
,
"jquery-knob/dist/jquery.knob.min.js"
,
"jquery-simple-slider/js/simple-slider.js"
,
"favico.js/favico.js"
,
"datatables/media/js/jquery.dataTables.js"
,
"autocomplete_light/jquery.init.js"
,
"autocomplete_light/autocomplete.init.js"
,
"autocomplete_light/vendor/select2/dist/js/select2.js"
,
"autocomplete_light/select2.js"
,
"dashboard/dashboard.js"
,
"dashboard/activity.js"
,
"dashboard/group-details.js"
,
"dashboard/group-list.js"
,
"dashboard/js/stupidtable.min.js"
,
# no bower file
"dashboard/node-create.js"
,
"dashboard/node-details.js"
,
"dashboard/node-list.js"
,
"dashboard/profile.js"
,
"dashboard/store.js"
,
"dashboard/template-list.js"
,
"dashboard/vm-common.js"
,
"dashboard/vm-create.js"
,
"dashboard/vm-list.js"
,
"dashboard/help.js"
,
"js/host.js"
,
"js/network.js"
,
"js/switch-port.js"
,
"js/host-list.js"
,
),
"output_filename"
:
"all.js"
,
},
"vm-detail"
:
{
"source_filenames"
:
(
"clipboard/dist/clipboard.min.js"
,
"dashboard/vm-details.js"
,
"no-vnc/include/util.js"
,
"no-vnc/include/webutil.js"
,
"no-vnc/include/base64.js"
,
"no-vnc/include/websock.js"
,
"no-vnc/include/des.js"
,
"no-vnc/include/keysym.js"
,
"no-vnc/include/keysymdef.js"
,
"no-vnc/include/keyboard.js"
,
"no-vnc/include/input.js"
,
"no-vnc/include/display.js"
,
"no-vnc/include/jsunzip.js"
,
"no-vnc/include/rfb.js"
,
"dashboard/vm-console.js"
,
"dashboard/vm-tour.js"
,
),
"output_filename"
:
"vm-detail.js"
,
},
"datastore"
:
{
"source_filenames"
:
(
"chart.js/dist/Chart.min.js"
,
"dashboard/datastore-details.js"
),
"output_filename"
:
"datastore.js"
,
},
},
}
########## SECRET CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
# Note: This key should only be used for development and testing.
...
...
@@ -279,26 +278,31 @@ FIXTURE_DIRS = (
########## TEMPLATE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors
TEMPLATE_CONTEXT_PROCESSORS
=
(
'django.contrib.auth.context_processors.auth'
,
'django.core.context_processors.debug'
,
'django.core.context_processors.i18n'
,
'django.core.context_processors.media'
,
'django.core.context_processors.static'
,
'django.core.context_processors.tz'
,
'django.contrib.messages.context_processors.messages'
,
'django.core.context_processors.request'
,
'dashboard.context_processors.notifications'
,
'dashboard.context_processors.extract_settings'
,
'dashboard.context_processors.broadcast_messages'
,
)
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs
TEMPLATE_DIRS
=
(
normpath
(
join
(
SITE_ROOT
,
'../../site-circle/templates'
)),
normpath
(
join
(
SITE_ROOT
,
'templates'
)),
)
# See: https://docs.djangoproject.com/en/dev/ref/settings/#TEMPLATES
TEMPLATES
=
[{
'BACKEND'
:
'django.template.backends.django.DjangoTemplates'
,
'DIRS'
:
(
normpath
(
join
(
SITE_ROOT
,
'../../site-circle/templates'
)),
normpath
(
join
(
SITE_ROOT
,
'templates'
)),
),
'APP_DIRS'
:
True
,
'OPTIONS'
:
{
'context_processors'
:
(
'django.contrib.auth.context_processors.auth'
,
'django.template.context_processors.debug'
,
'django.template.context_processors.i18n'
,
'django.template.context_processors.media'
,
'django.template.context_processors.static'
,
'django.template.context_processors.tz'
,
'django.contrib.messages.context_processors.messages'
,
'django.template.context_processors.request'
,
'dashboard.context_processors.notifications'
,
'dashboard.context_processors.extract_settings'
,
'dashboard.context_processors.broadcast_messages'
,
),
},
}]
########## END TEMPLATE CONFIGURATION
...
...
@@ -336,6 +340,10 @@ DJANGO_APPS = (
# Useful template tags:
# 'django.contrib.humanize',
# Django autocomplete light
# it needs registering before django admin
'dal'
,
'dal_select2'
,
# Admin panel and documentation:
'django.contrib.admin'
,
# 'django.contrib.admindocs',
...
...
@@ -348,7 +356,6 @@ THIRD_PARTY_APPS = (
'taggit'
,
'statici18n'
,
'django_sshkey'
,
'autocomplete_light'
,
'pipeline'
,
)
...
...
circle/circle/settings/local.py
View file @
53dbd80b
...
...
@@ -27,7 +27,7 @@ from base import * # noqa
DEBUG
=
True
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug
TEMPLATE
_DEBUG
=
DEBUG
TEMPLATE
S
[
0
][
'OPTIONS'
][
'debug'
]
=
DEBUG
########## END DEBUG CONFIGURATION
SECURE_PROXY_SSL_HEADER
=
(
'HTTP_X_FORWARDED_PROTOCOL'
,
'https'
)
...
...
@@ -110,8 +110,10 @@ if DEBUG:
from
django.dispatch
import
Signal
Signal
.
send_robust
=
Signal
.
send
PIPELINE
_COMPILERS
=
(
PIPELINE
[
"COMPILERS"
]
=
(
'dashboard.compilers.DummyLessCompiler'
,
)
ADMIN_ENABLED
=
True
ALLOWED_HOSTS
=
[
'*'
]
circle/circle/settings/selenium_test.py
View file @
53dbd80b
...
...
@@ -14,9 +14,10 @@
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
import
os
from
.base
import
*
# noqa
from
.base
import
*
#
flake8:
noqa
# fix https://github.com/django-nose/django-nose/issues/197
...
...
circle/circle/settings/test.py
View file @
53dbd80b
...
...
@@ -38,7 +38,11 @@ INSTALLED_APPS += (
'django_nose'
,
)
TEST_RUNNER
=
'django_nose.NoseTestSuiteRunner'
NOSE_ARGS
=
[
'--with-doctest'
,
'--exclude-dir=dashboard/tests/selenium'
]
NOSE_ARGS
=
[
'--with-doctest'
,
'--exclude-dir=dashboard/tests/selenium'
,
'--exclude=circle'
]
PASSWORD_HASHERS
=
[
'django.contrib.auth.hashers.MD5PasswordHasher'
]
CACHES
=
{
...
...
@@ -59,7 +63,7 @@ for i in LOCAL_APPS:
# don't print SQL queries
LOGGING
[
'handlers'
][
'null'
]
=
{
'level'
:
"DEBUG"
,
'class'
:
"
django.utils.lo
g.NullHandler"
}
'class'
:
"
loggin
g.NullHandler"
}
LOGGING
[
'loggers'
][
'django.db.backends'
]
=
{
'handlers'
:
[
'null'
],
'propagate'
:
False
,
...
...
circle/circle/urls.py
View file @
53dbd80b
...
...
@@ -15,13 +15,16 @@
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from
django.conf.urls
import
patterns
,
include
,
url
from
django.conf.urls
import
include
,
url
from
django.views.generic
import
TemplateView
from
django.conf
import
settings
from
django.contrib
import
admin
from
django.core.urlresolvers
import
reverse
from
django.shortcuts
import
redirect
from
django.contrib.auth.views
import
(
password_reset_confirm
,
password_reset
)
from
circle.settings.base
import
get_env_variable
...
...
@@ -33,9 +36,7 @@ from firewall.views import add_blacklist_item
admin
.
autodiscover
()
urlpatterns
=
patterns
(
''
,
urlpatterns
=
[
url
(
r'^$'
,
lambda
x
:
redirect
(
reverse
(
"dashboard.index"
))),
url
(
r'^network/'
,
include
(
'network.urls'
)),
url
(
r'^blacklist-add/'
,
add_blacklist_item
),
...
...
@@ -45,12 +46,11 @@ urlpatterns = patterns(
# django/contrib/auth/urls.py (care when new version)
url
((
r'^accounts/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/'
r'(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$'
),
'django.contrib.auth.views.password_reset_confirm'
,
password_reset_confirm
,
{
'set_password_form'
:
CircleSetPasswordForm
},
name
=
'accounts.password_reset_confirm'
),
url
(
r'^accounts/password/reset/$'
,
(
"django.contrib.auth.views."
"password_reset"
),
url
(
r'^accounts/password/reset/$'
,
password_reset
,
{
'password_reset_form'
:
CirclePasswordResetForm
},
name
=
"accounts.password-reset"
,
),
...
...
@@ -73,27 +73,24 @@ urlpatterns = patterns(
name
=
"info.support"
),
url
(
r'^info/resize-how-to/$'
,
ResizeHelpView
.
as_view
(),
name
=
"info.resize"
),
)
]
if
'rosetta'
in
settings
.
INSTALLED_APPS
:
urlpatterns
+=
patterns
(
''
,
urlpatterns
+=
[
url
(
r'^rosetta/'
,
include
(
'rosetta.urls'
)),
)
]
if
settings
.
ADMIN_ENABLED
:
urlpatterns
+=
patterns
(
''
,
urlpatterns
+=
[
url
(
r'^admin/'
,
include
(
admin
.
site
.
urls
)),
)
]
if
get_env_variable
(
'DJANGO_SAML'
,
'FALSE'
)
==
'TRUE'
:
urlpatterns
+=
patterns
(
''
,
urlpatterns
+=
[
(
r'^saml2/'
,
include
(
'djangosaml2.urls'
)),
)
]
handler500
=
'common.views.handler500'
handler403
=
'common.views.handler403'
circle/common/views.py
View file @
53dbd80b
...
...
@@ -45,7 +45,8 @@ def handler500(request):
logger
.
exception
(
"unhandled exception"
)
ctx
=
get_context
(
request
,
exception
)
try
:
resp
=
render_to_response
(
"500.html"
,
ctx
,
RequestContext
(
request
))
resp
=
render_to_response
(
"500.html"
,
ctx
,
RequestContext
(
request
)
.
flatten
())
except
:
resp
=
render_to_response
(
"500.html"
,
ctx
)
resp
.
status_code
=
500
...
...
circle/dashboard/forms.py
View file @
53dbd80b
...
...
@@ -31,7 +31,7 @@ from django.contrib.auth.models import User, Group
from
django.core.validators
import
URLValidator
from
django.core.exceptions
import
PermissionDenied
,
ValidationError
import
autocomplete_light
from
dal
import
autocomplete
from
crispy_forms.helper
import
FormHelper
from
crispy_forms.layout
import
(
Layout
,
Div
,
BaseInput
,
Field
,
HTML
,
Submit
,
TEMPLATE_PACK
,
Fieldset
...
...
@@ -43,7 +43,6 @@ from crispy_forms.bootstrap import FormActions
from
django
import
forms
from
django.contrib.auth.forms
import
UserCreationForm
as
OrgUserCreationForm
from
django.forms.widgets
import
TextInput
,
HiddenInput
from
django.template
import
Context
from
django.template.loader
import
render_to_string
from
django.utils.html
import
escape
,
format_html
from
django.utils.safestring
import
mark_safe
...
...
@@ -67,6 +66,7 @@ from .validators import domain_validator
from
dashboard.models
import
ConnectCommand
,
create_profile
LANGUAGES_WITH_CODE
=
((
l
[
0
],
string_concat
(
l
[
1
],
" ("
,
l
[
0
],
")"
))
for
l
in
LANGUAGES
)
...
...
@@ -1180,8 +1180,7 @@ class AnyTag(Div):
fields
+=
render_field
(
field
,
form
,
form_style
,
context
,
template_pack
=
template_pack
)
return
render_to_string
(
self
.
template
,
Context
({
'tag'
:
self
,
'fields'
:
fields
}))
return
render_to_string
(
self
.
template
,
{
'tag'
:
self
,
'fields'
:
fields
})
class
WorkingBaseInput
(
BaseInput
):
...
...
@@ -1334,27 +1333,31 @@ class UserEditForm(forms.ModelForm):
class
AclUserOrGroupAddForm
(
forms
.
Form
):
name
=
forms
.
CharField
(
widget
=
autocomplete_light
.
TextWidget
(
'AclUserGroupAutocomplete'
,
attrs
=
{
'class'
:
'form-control'
,
'placeholder'
:
_
(
"Name of group or user"
)}))
name
=
forms
.
CharField
(
widget
=
autocomplete
.
ListSelect2
(
url
=
'autocomplete.acl.user-group'
,
attrs
=
{
'class'
:
'form-control'
,
'data-html'
:
'true'
,
'data-placeholder'
:
_
(
"Name of group or user"
)}))
class
TransferOwnershipForm
(
forms
.
Form
):
name
=
forms
.
CharField
(
widget
=
autocomplete
_light
.
TextWidget
(
'AclUserAutocomplete
'
,
widget
=
autocomplete
.
ListSelect2
(
url
=
'autocomplete.acl.user
'
,
attrs
=
{
'class'
:
'form-control'
,
'placeholder'
:
_
(
"Name of user"
)}),
'data-html'
:
'true'
,
'data-placeholder'
:
_
(
"Name of user"
)}),
label
=
_
(
"E-mail address or identifier of user"
))
class
AddGroupMemberForm
(
forms
.
Form
):
new_member
=
forms
.
CharField
(
widget
=
autocomplete
_light
.
TextWidget
(
'AclUserAutocomplete
'
,
widget
=
autocomplete
.
ListSelect2
(
url
=
'autocomplete.acl.user
'
,
attrs
=
{
'class'
:
'form-control'
,
'placeholder'
:
_
(
"Name of user"
)}),
'data-html'
:
'true'
,
'data-placeholder'
:
_
(
"Name of user"
)}),
label
=
_
(
"E-mail address or identifier of user"
))
...
...
circle/dashboard/management/commands/init.py
View file @
53dbd80b
...
...
@@ -18,7 +18,6 @@
from
__future__
import
unicode_literals
,
absolute_import
import
logging
from
optparse
import
make_option
from
django.contrib.auth.models
import
User
from
django.core.management.base
import
BaseCommand
...
...
@@ -32,19 +31,18 @@ logger = logging.getLogger(__name__)
class
Command
(
BaseCommand
):
option_list
=
BaseCommand
.
option_list
+
(
make_option
(
'--force'
,
action
=
"store_true"
),
make_option
(
'--external-net'
),
make_option
(
'--management-net'
),
make_option
(
'--vm-net'
),
make_option
(
'--external-if'
),
make_option
(
'--management-if'
),
make_option
(
'--vm-if'
),
make_option
(
'--datastore-queue'
),
make_option
(
'--firewall-queue'
),
make_option
(
'--admin-user'
),
make_option
(
'--admin-pass'
),
)
def
add_arguments
(
self
,
parser
):
parser
.
add_argument
(
'--force'
,
action
=
"store_true"
)
parser
.
add_argument
(
'--external-net'
)
parser
.
add_argument
(
'--management-net'
)
parser
.
add_argument
(
'--vm-net'
)
parser
.
add_argument
(
'--external-if'
)
parser
.
add_argument
(
'--management-if'
)
parser
.
add_argument
(
'--vm-if'
)
parser
.
add_argument
(
'--datastore-queue'
)
parser
.
add_argument
(
'--firewall-queue'
)
parser
.
add_argument
(
'--admin-user'
)
parser
.
add_argument
(
'--admin-pass'
)
def
create
(
self
,
model
,
field
,
**
kwargs
):
value
=
kwargs
[
field
]
...
...
@@ -59,14 +57,15 @@ class Command(BaseCommand):
# http://docs.saltstack.com/en/latest/ref/states/all/salt.states.cmd.html
def
print_state
(
self
):
print
"
\n
changed=
%
s"
%
(
"yes"
if
self
.
changed
else
"no"
)
self
.
stdout
.
write
(
"
\n
changed=
%
s"
%
(
"yes"
if
self
.
changed
else
"no"
)
)
def
handle
(
self
,
*
args
,
**
options
):
self
.
changed
=
False
if
(
DataStore
.
objects
.
exists
()
and
Vlan
.
objects
.
exists
()
and
not
options
[
'force'
]):
return
self
.
print_state
()
self
.
print_state
()
return
admin
=
self
.
create
(
User
,
'username'
,
username
=
options
[
'admin_user'
],
is_superuser
=
True
,
is_staff
=
True
)
...
...
@@ -153,4 +152,4 @@ class Command(BaseCommand):
direction
=
'out'
,
action
=
'accept'
,
foreign_network
=
vg_net
,
vlan
=
man
)
return
self
.
print_state
()
self
.
print_state
()
circle/dashboard/migrations/0006_auto_20170707_1909.py
0 → 100644
View file @
53dbd80b
# -*- coding: utf-8 -*-
# Generated by Django 1.11.3 on 2017-07-07 19:09
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'dashboard'
,
'0005_profile_two_factor_secret'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'connectcommand'
,
name
=
'name'
,
field
=
models
.
CharField
(
help_text
=
'Name of your custom command.'
,
max_length
=
128
,
verbose_name
=
'name'
),
),
]
circle/dashboard/models.py
View file @
53dbd80b
...
...
@@ -151,7 +151,7 @@ class ConnectCommand(Model):
access_method
=
CharField
(
max_length
=
10
,
choices
=
ACCESS_METHODS
,
verbose_name
=
_
(
'access method'
),
help_text
=
_
(
'Type of the remote access method.'
))
name
=
CharField
(
max_length
=
"128"
,
verbose_name
=
_
(
'name'
),
blank
=
False
,
name
=
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'name'
),
blank
=
False
,
help_text
=
_
(
"Name of your custom command."
))
template
=
CharField
(
blank
=
True
,
null
=
True
,
max_length
=
256
,
verbose_name
=
_
(
'command template'
),
...
...
circle/dashboard/static/dashboard/dashboard.js
View file @
53dbd80b
...
...
@@ -508,13 +508,6 @@ $.ajaxSetup({
}
});
/* for autocomplete */
$
(
function
()
{
yourlabs
.
TextWidget
.
prototype
.
getValue
=
function
(
choice
)
{
return
choice
.
children
().
html
();
};
});
var
tagsToReplace
=
{
'&'
:
'&'
,
'<'
:
'<'
,
...
...
circle/dashboard/static/dashboard/dashboard.less
View file @
53dbd80b
...
...
@@ -1031,7 +1031,7 @@ textarea[name="new_members"] {
font-weight: bold;
}
.
hilight
.autocomplete-hl {
.
select2-results__option--highlighted
.autocomplete-hl {
color: orange;
}
...
...
circle/dashboard/templates/dashboard/_manage_access.html
View file @
53dbd80b
...
...
@@ -24,7 +24,7 @@
<td>
<select
class=
"form-control"
name=
"perm-u-{{i.user.id}}"
{%
if
i
.
level
not
in
acl
.
allowed_levels
%}
disabled
{%
endif
%}
>
{% for id, name in acl.levels %}
<option
{%
if
id =
i.level%}
selected=
"selected"
{%
endif
%}
<option
{%
if
id =
=
i
.
level
%}
selected=
"selected"
{%
endif
%}
{%
if
id
not
in
acl
.
allowed_levels
%}
disabled
{%
endif
%}
value=
"{{id}}"
>
{{name}}
</option>
{% endfor %}
...
...
@@ -46,7 +46,7 @@
<td>
<select
class=
"form-control"
name=
"perm-g-{{i.group.id}}{% if i.level not in acl.allowed_levels %} disabled{% endif %}"
>
{% for id, name in acl.levels %}
<option
{%
if
id =
i.level%}
selected=
"selected"
{%
endif
%}
<option
{%
if
id =
=
i
.
level
%}
selected=
"selected"
{%
endif
%}
{%
if
id
not
in
acl
.
allowed_levels
%}
disabled
{%
endif
%}
value=
"{{id}}"
>
{{name}}
</option>
{% endfor %}
...
...
circle/dashboard/templates/dashboard/group-detail.html
View file @
53dbd80b
...
...
@@ -137,8 +137,10 @@
{% if user.is_superuser %}
<hr
/>
<script
type=
"text/javascript"
src=
"/static/admin/js/jquery.min.js"
></script>
<script
type=
"text/javascript"
src=
"/static/admin/js/jquery.init.js"
></script>
<script
type=
"text/javascript"
src=
"/static/admin/js/vendor/jquery/jquery.min.js"
></script>
<script
type=
"text/javascript"
src=
"/static/admin/js/jquery.init.js"
></script>
<script
type=
"text/javascript"
src=
"/static/autocomplete_light/jquery.init.js"
></script>
<script
type=
"text/javascript"
src=
"/static/autocomplete_light/vendor/select2/dist/js/select2.js"
></script>
{{ group_perm_form.media }}
<h3>
{% trans "Group permissions" %}
</h3>
...
...
circle/dashboard/templates/dashboard/lease-edit.html
View file @
53dbd80b
...
...
@@ -52,7 +52,7 @@
<td>
<select
class=
"form-control"
name=
"perm-u-{{i.user.id}}"
>
{% for id, name in acl.levels %}
<option
{%
if
id =
i.level%}
selected=
"selected"
{%
endif
%}
value=
"{{id}}"
>
{{name}}
</option>
<option
{%
if
id =
=
i
.
level
%}
selected=
"selected"
{%
endif
%}
value=
"{{id}}"
>
{{name}}
</option>
{% endfor %}
</select>
</td>
...
...
@@ -72,7 +72,7 @@
<td>
<select
class=
"form-control"
name=
"perm-g-{{i.group.id}}"
>
{% for id, name in acl.levels %}
<option
{%
if
id =
i.level%}
selected=
"selected"
{%
endif
%}
value=
"{{id}}"
>
{{name}}
</option>
<option
{%
if
id =
=
i
.
level
%}
selected=
"selected"
{%
endif
%}
value=
"{{id}}"
>
{{name}}
</option>
{% endfor %}
</select>
</td>
...
...
circle/dashboard/templates/django_tables2/table_no_page.html
View file @
53dbd80b
...
...
@@ -4,9 +4,9 @@
{% if table.page %}
<div
class=
"table-container"
>
{% endif %}
{% endspaceless %}
{% block table %}
<table
{%
if
table
.
attrs
%}
{{
table
.
attrs
.
as_html
}}{%
endif
%}
>
{% nospaceless %}
{% block table.thead %}
<thead>
<tr>
...
...
@@ -42,10 +42,9 @@
{% block table.tfoot %}
<tfoot></tfoot>
{% endblock table.tfoot %}
{% endnospaceless %}
</table>