Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
18fd04d6
Commit
18fd04d6
authored
Dec 08, 2017
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Stash] Test case 通不过,import error
parent
27a1849b
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
113 additions
and
238 deletions
+113
-238
models.py
apps/assets/models.py
+2
-0
__init__.py
apps/assets/models/__init__.py
+3
-2
asset.py
apps/assets/models/asset.py
+3
-3
group.py
apps/assets/models/group.py
+1
-1
admin_user_detail.html
apps/assets/templates/assets/admin_user_detail.html
+1
-1
asset_update.html
apps/assets/templates/assets/asset_update.html
+1
-1
cluster_list.html
apps/assets/templates/assets/cluster_list.html
+15
-15
asset.py
apps/assets/views/asset.py
+7
-6
django.po
apps/locale/zh/LC_MESSAGES/django.po
+1
-1
test_inventory.bak
apps/ops/ansible/test_inventory.bak
+0
-0
test_runner.bak
apps/ops/ansible/test_runner.bak
+0
-0
models.py
apps/ops/models.py
+3
-2
test_utils.py
apps/ops/test_utils.py
+34
-0
utils.py
apps/ops/utils.py
+36
-12
models.py
apps/perms/models.py
+2
-5
authentication.py
apps/users/models/authentication.py
+1
-1
user.py
apps/users/models/user.py
+1
-1
utils.py
apps/users/models/utils.py
+2
-1
base.py
apps/users/tests/base.py
+0
-25
test_models.py
apps/users/tests/test_models.py
+0
-95
test_views.py
apps/users/tests/test_views.py
+0
-66
No files found.
apps/assets/models.py
0 → 100644
View file @
18fd04d6
# -*- coding: utf-8 -*-
#
apps/assets/models/__init__.py
View file @
18fd04d6
#!/usr/bin/env python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
print
(
"Import assets model"
)
from
.user
import
AdminUser
,
SystemUser
from
.cluster
import
*
from
.cluster
import
*
from
.user
import
*
from
.group
import
*
from
.group
import
*
from
.asset
import
*
from
.asset
import
*
from
.utils
import
*
from
.utils
import
*
apps/assets/models/asset.py
View file @
18fd04d6
...
@@ -2,15 +2,15 @@
...
@@ -2,15 +2,15 @@
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
from
__future__
import
unicode_literals
import
uuid
import
uuid
from
django.db
import
models
from
django.db
import
models
import
logging
import
logging
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
.
import
Cluster
,
AssetGroup
,
AdminUser
,
SystemUser
from
.cluster
import
Cluster
from
.group
import
AssetGroup
from
.user
import
AdminUser
,
SystemUser
__all__
=
[
'Asset'
]
__all__
=
[
'Asset'
]
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
...
...
apps/assets/models/group.py
View file @
18fd04d6
...
@@ -10,7 +10,7 @@ from django.db import models
...
@@ -10,7 +10,7 @@ from django.db import models
import
logging
import
logging
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
.
import
SystemUser
from
.
user
import
SystemUser
__all__
=
[
'AssetGroup'
]
__all__
=
[
'AssetGroup'
]
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
...
...
apps/assets/templates/assets/admin_user_detail.html
View file @
18fd04d6
...
@@ -321,7 +321,7 @@ $(document).ready(function () {
...
@@ -321,7 +321,7 @@ $(document).ready(function () {
var
body
=
{};
var
body
=
{};
var
success
=
function
()
{
var
success
=
function
()
{
swal
(
'Deleted!'
,
"[ "
+
name
+
"]"
+
" has been deleted "
,
"success"
);
swal
(
'Deleted!'
,
"[ "
+
name
+
"]"
+
" has been deleted "
,
"success"
);
window
.
location
.
href
=
"{% url 'assets:
idc
-list' %}"
;
window
.
location
.
href
=
"{% url 'assets:
cluster
-list' %}"
;
};
};
var
fail
=
function
()
{
var
fail
=
function
()
{
swal
(
"Failed"
,
"Delete"
+
"[ "
+
name
+
" ]"
+
"failed"
,
"error"
);
swal
(
"Failed"
,
"Delete"
+
"[ "
+
name
+
" ]"
+
"failed"
,
"error"
);
...
...
apps/assets/templates/assets/asset_update.html
View file @
18fd04d6
...
@@ -25,7 +25,7 @@
...
@@ -25,7 +25,7 @@
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Group' %}
</h3>
<h3>
{% trans 'Group' %}
</h3>
{% bootstrap_field form.
idc
layout="horizontal" %}
{% bootstrap_field form.
cluster
layout="horizontal" %}
{% bootstrap_field form.groups layout="horizontal" %}
{% bootstrap_field form.groups layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
...
...
apps/assets/templates/assets/cluster_list.html
View file @
18fd04d6
...
@@ -7,15 +7,15 @@
...
@@ -7,15 +7,15 @@
{% block table_search %}{% endblock %}
{% block table_search %}{% endblock %}
{% block table_container %}
{% block table_container %}
<div
class=
"uc pull-left m-l-5 m-r-5"
>
<div
class=
"uc pull-left m-l-5 m-r-5"
>
<a
href=
"{% url "
assets:
idc
-create
"
%}"
class=
"btn btn-sm btn-primary"
>
{% trans "Create Cluster" %}
</a>
<a
href=
"{% url "
assets:
cluster
-create
"
%}"
class=
"btn btn-sm btn-primary"
>
{% trans "Create Cluster" %}
</a>
</div>
</div>
<table
class=
"table table-striped table-bordered table-hover "
id=
"
idc
_list_table"
>
<table
class=
"table table-striped table-bordered table-hover "
id=
"
cluster
_list_table"
>
<thead>
<thead>
<tr>
<tr>
<th
class=
"text-center"
>
<th
class=
"text-center"
>
<input
type=
"checkbox"
id=
"check_all"
class=
"ipt_check_all"
>
<input
type=
"checkbox"
id=
"check_all"
class=
"ipt_check_all"
>
</th>
</th>
<th
class=
"text-center"
><a
href=
"{% url 'assets:
idc
-list' %}?sort=name"
>
{% trans 'Name' %}
</a></th>
<th
class=
"text-center"
><a
href=
"{% url 'assets:
cluster
-list' %}?sort=name"
>
{% trans 'Name' %}
</a></th>
<th
class=
"text-center"
>
{% trans 'Asset num' %}
</th>
<th
class=
"text-center"
>
{% trans 'Asset num' %}
</th>
<th
class=
"text-center"
>
{% trans 'Contact' %}
</th>
<th
class=
"text-center"
>
{% trans 'Contact' %}
</th>
<th
class=
"text-center"
>
{% trans 'Phone' %}
</th>
<th
class=
"text-center"
>
{% trans 'Phone' %}
</th>
...
@@ -44,19 +44,19 @@
...
@@ -44,19 +44,19 @@
<script>
<script>
$
(
document
).
ready
(
function
(){
$
(
document
).
ready
(
function
(){
var
options
=
{
var
options
=
{
ele
:
$
(
'#
idc
_list_table'
),
ele
:
$
(
'#
cluster
_list_table'
),
columnDefs
:
[
columnDefs
:
[
{
targets
:
1
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
{
targets
:
1
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
var
detail_btn
=
'<a href="{% url "assets:
idc
-detail" pk=99991937 %}">'
+
cellData
+
'</a>'
;
var
detail_btn
=
'<a href="{% url "assets:
cluster
-detail" pk=99991937 %}">'
+
cellData
+
'</a>'
;
$
(
td
).
html
(
detail_btn
.
replace
(
'99991937'
,
rowData
.
id
));
$
(
td
).
html
(
detail_btn
.
replace
(
'99991937'
,
rowData
.
id
));
}},
}},
{
targets
:
6
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
{
targets
:
6
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
var
update_btn
=
'<a href="{% url "assets:
idc
-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'
.
replace
(
'99991937'
,
cellData
);
var
update_btn
=
'<a href="{% url "assets:
cluster
-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'
.
replace
(
'99991937'
,
cellData
);
var
del_btn
=
'<a class="btn btn-xs btn-danger m-l-xs btn_
idc
_delete" data-uid="99991937">{% trans "Delete" %}</a>'
.
replace
(
'99991937'
,
cellData
);
var
del_btn
=
'<a class="btn btn-xs btn-danger m-l-xs btn_
cluster
_delete" data-uid="99991937">{% trans "Delete" %}</a>'
.
replace
(
'99991937'
,
cellData
);
$
(
td
).
html
(
update_btn
+
del_btn
)
$
(
td
).
html
(
update_btn
+
del_btn
)
}}],
}}],
ajax_url
:
'{% url "api-assets:
idc
-list" %}'
,
ajax_url
:
'{% url "api-assets:
cluster
-list" %}'
,
columns
:
[{
data
:
function
(){
return
""
}},
{
data
:
"name"
},
{
data
:
"assets_amount"
},
{
data
:
"contact"
},
{
data
:
"phone"
},
columns
:
[{
data
:
function
(){
return
""
}},
{
data
:
"name"
},
{
data
:
"assets_amount"
},
{
data
:
"contact"
},
{
data
:
"phone"
},
{
data
:
"operator"
},
{
data
:
"id"
}],
{
data
:
"operator"
},
{
data
:
"id"
}],
op_html
:
$
(
'#actions'
).
html
()
op_html
:
$
(
'#actions'
).
html
()
...
@@ -64,12 +64,12 @@ $(document).ready(function(){
...
@@ -64,12 +64,12 @@ $(document).ready(function(){
jumpserver
.
initDataTable
(
options
);
jumpserver
.
initDataTable
(
options
);
})
})
.
on
(
'click'
,
'.btn_
idc
_delete'
,
function
()
{
.
on
(
'click'
,
'.btn_
cluster
_delete'
,
function
()
{
var
$this
=
$
(
this
);
var
$this
=
$
(
this
);
var
$data_table
=
$
(
'#
idc
_list_table'
).
DataTable
();
var
$data_table
=
$
(
'#
cluster
_list_table'
).
DataTable
();
var
name
=
$
(
this
).
closest
(
"tr"
).
find
(
":nth-child(2)"
).
children
(
'a'
).
html
();
var
name
=
$
(
this
).
closest
(
"tr"
).
find
(
":nth-child(2)"
).
children
(
'a'
).
html
();
var
uid
=
$this
.
data
(
'uid'
);
var
uid
=
$this
.
data
(
'uid'
);
var
the_url
=
'{% url "api-assets:
idc
-detail" pk=99991937 %}'
.
replace
(
'99991937'
,
uid
);
var
the_url
=
'{% url "api-assets:
cluster
-detail" pk=99991937 %}'
.
replace
(
'99991937'
,
uid
);
objectDelete
(
$this
,
name
,
the_url
);
objectDelete
(
$this
,
name
,
the_url
);
setTimeout
(
function
()
{
setTimeout
(
function
()
{
$data_table
.
ajax
.
reload
();
$data_table
.
ajax
.
reload
();
...
@@ -78,7 +78,7 @@ $(document).ready(function(){
...
@@ -78,7 +78,7 @@ $(document).ready(function(){
.
on
(
'click'
,
'#btn_bulk_update'
,
function
()
{
.
on
(
'click'
,
'#btn_bulk_update'
,
function
()
{
var
action
=
$
(
'#slct_bulk_update'
).
val
();
var
action
=
$
(
'#slct_bulk_update'
).
val
();
var
$data_table
=
$
(
'#
idc
_list_table'
).
DataTable
();
var
$data_table
=
$
(
'#
cluster
_list_table'
).
DataTable
();
var
id_list
=
[];
var
id_list
=
[];
var
plain_id_list
=
[];
var
plain_id_list
=
[];
$data_table
.
rows
({
selected
:
true
}).
every
(
function
(){
$data_table
.
rows
({
selected
:
true
}).
every
(
function
(){
...
@@ -88,11 +88,11 @@ $(document).ready(function(){
...
@@ -88,11 +88,11 @@ $(document).ready(function(){
if
(
id_list
===
[])
{
if
(
id_list
===
[])
{
return
false
;
return
false
;
}
}
var
the_url
=
"{% url 'api-assets:
idc
-list' %}"
;
var
the_url
=
"{% url 'api-assets:
cluster
-list' %}"
;
function
doDelete
()
{
function
doDelete
()
{
swal
({
swal
({
title
:
"{% trans 'Are you sure?' %}"
,
title
:
"{% trans 'Are you sure?' %}"
,
text
:
"{% trans 'This will delete the selected
idc
' %}"
,
text
:
"{% trans 'This will delete the selected
cluster
' %}"
,
type
:
"warning"
,
type
:
"warning"
,
showCancelButton
:
true
,
showCancelButton
:
true
,
confirmButtonColor
:
"#DD6B55"
,
confirmButtonColor
:
"#DD6B55"
,
...
@@ -102,7 +102,7 @@ $(document).ready(function(){
...
@@ -102,7 +102,7 @@ $(document).ready(function(){
var
success
=
function
()
{
var
success
=
function
()
{
var
msg
=
"{% trans 'Cluster Deleted.' %}"
;
var
msg
=
"{% trans 'Cluster Deleted.' %}"
;
swal
(
"{% trans 'Cluster Delete' %}"
,
msg
,
"success"
);
swal
(
"{% trans 'Cluster Delete' %}"
,
msg
,
"success"
);
$
(
'#
idc
_list_table'
).
DataTable
().
ajax
.
reload
();
$
(
'#
cluster
_list_table'
).
DataTable
().
ajax
.
reload
();
};
};
var
fail
=
function
()
{
var
fail
=
function
()
{
var
msg
=
"{% trans 'Cluster Deleting failed.' %}"
;
var
msg
=
"{% trans 'Cluster Deleting failed.' %}"
;
...
...
apps/assets/views/asset.py
View file @
18fd04d6
...
@@ -30,11 +30,12 @@ from ..hands import AdminUserRequiredMixin
...
@@ -30,11 +30,12 @@ from ..hands import AdminUserRequiredMixin
from
..tasks
import
update_assets_hardware_info
from
..tasks
import
update_assets_hardware_info
__all__
=
[
'AssetListView'
,
'AssetCreateView'
,
'AssetUpdateView'
,
__all__
=
[
'UserAssetListView'
,
'AssetBulkUpdateView'
,
'AssetDetailView'
,
'AssetListView'
,
'AssetCreateView'
,
'AssetUpdateView'
,
'AssetModalListView'
,
'AssetDeleteView'
,
'AssetExportView'
,
'UserAssetListView'
,
'AssetBulkUpdateView'
,
'AssetDetailView'
,
'BulkImportAssetView'
,
'AssetModalListView'
,
'AssetDeleteView'
,
'AssetExportView'
,
]
'BulkImportAssetView'
,
]
class
AssetListView
(
AdminUserRequiredMixin
,
TemplateView
):
class
AssetListView
(
AdminUserRequiredMixin
,
TemplateView
):
...
@@ -282,7 +283,7 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
...
@@ -282,7 +283,7 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
asset
=
get_object_or_none
(
Asset
,
id
=
id_
)
asset
=
get_object_or_none
(
Asset
,
id
=
id_
)
for
k
,
v
in
asset_dict
.
items
():
for
k
,
v
in
asset_dict
.
items
():
if
k
==
'
idc
'
:
if
k
==
'
cluster
'
:
v
=
get_object_or_none
(
Cluster
,
name
=
v
)
v
=
get_object_or_none
(
Cluster
,
name
=
v
)
elif
k
==
'is_active'
:
elif
k
==
'is_active'
:
v
=
bool
(
v
)
v
=
bool
(
v
)
...
...
apps/locale/zh/LC_MESSAGES/django.po
View file @
18fd04d6
...
@@ -1108,7 +1108,7 @@ msgid "Create Cluster"
...
@@ -1108,7 +1108,7 @@ msgid "Create Cluster"
msgstr "创建Cluster"
msgstr "创建Cluster"
#: assets/templates/assets/idc_list.html:95
#: assets/templates/assets/idc_list.html:95
msgid "This will delete the selected
idc
"
msgid "This will delete the selected
cluster
"
msgstr "删除选择Cluster"
msgstr "删除选择Cluster"
#: assets/templates/assets/idc_list.html:103
#: assets/templates/assets/idc_list.html:103
...
...
apps/ops/ansible/test_inventory.
py
→
apps/ops/ansible/test_inventory.
bak
View file @
18fd04d6
File moved
apps/ops/ansible/test_runner.
py
→
apps/ops/ansible/test_runner.
bak
View file @
18fd04d6
File moved
apps/ops/models.py
View file @
18fd04d6
...
@@ -18,7 +18,8 @@ class AdHoc(models.Model):
...
@@ -18,7 +18,8 @@ class AdHoc(models.Model):
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
name
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
verbose_name
=
_
(
'Name'
))
name
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
verbose_name
=
_
(
'Name'
))
is_deleted
=
models
.
BooleanField
(
default
=
False
)
is_deleted
=
models
.
BooleanField
(
default
=
False
)
date_create
=
models
.
DateTimeField
(
auto_created
=
True
)
created_by
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
default
=
''
)
date_create
=
models
.
DateTimeField
(
auto_now_add
=
True
)
@property
@property
def
short_id
(
self
):
def
short_id
(
self
):
...
@@ -45,7 +46,7 @@ class AdHocData(models.Model):
...
@@ -45,7 +46,7 @@ class AdHocData(models.Model):
_become_pass
=
models
.
CharField
(
default
=
''
,
max_length
=
128
)
_become_pass
=
models
.
CharField
(
default
=
''
,
max_length
=
128
)
pattern
=
models
.
CharField
(
max_length
=
64
,
default
=
''
,
verbose_name
=
_
(
'Pattern'
))
pattern
=
models
.
CharField
(
max_length
=
64
,
default
=
''
,
verbose_name
=
_
(
'Pattern'
))
created_by
=
models
.
CharField
(
max_length
=
64
,
verbose_name
=
_
(
'Create by'
))
created_by
=
models
.
CharField
(
max_length
=
64
,
verbose_name
=
_
(
'Create by'
))
date_created
=
models
.
DateTimeField
(
auto_
create
d
=
True
)
date_created
=
models
.
DateTimeField
(
auto_
now_ad
d
=
True
)
@property
@property
def
tasks
(
self
):
def
tasks
(
self
):
...
...
apps/ops/test_utils.py
0 → 100644
View file @
18fd04d6
# -*- coding: utf-8 -*-
#
import
sys
import
os
from
django.test
import
TestCase
os
.
environ
.
setdefault
(
"DJANGO_SETTINGS_MODULE"
,
"jumpserver.settings"
)
from
ops.models
import
AdHoc
,
AdHocData
from
ops.utils
import
run_adhoc
class
TestRunAdHoc
(
TestCase
):
def
setUp
(
self
):
adhoc
=
AdHoc
(
name
=
"Test run adhoc"
)
adhoc
.
save
()
self
.
data
=
AdHocData
(
subject
=
adhoc
,
run_as_admin
=
True
,
pattern
=
'all'
)
self
.
data
.
tasks
=
[
{
'name'
:
'run ls'
,
'action'
:
{
'module'
:
'shell'
,
'args'
:
'ls'
}},
{
'name'
:
'echo '
,
'action'
:
{
'module'
:
'shell'
,
'args'
:
'echo 123'
}},
]
self
.
data
.
hosts
=
[
"testserver"
]
def
test_run
(
self
):
pass
apps/ops/utils.py
View file @
18fd04d6
# ~*~ coding: utf-8 ~*~
# ~*~ coding: utf-8 ~*~
from
__future__
import
absolute_import
,
unicode_literals
import
json
import
re
import
re
import
time
import
uuid
import
time
from
django.utils
import
timezone
from
django.utils
import
timezone
from
common.utils
import
get_logger
,
get_object_or_none
from
common.utils
import
get_logger
,
get_object_or_none
from
.ansible
import
AdHocRunner
from
.ansible
import
AdHocRunner
from
.ansible.exceptions
import
AnsibleError
from
.models
import
AdHocRunHistory
from
assets.utils
import
get_assets_by_hostname_list
from
assets.utils
import
get_assets_by_hostname_list
logger
=
get_logger
(
__file__
)
logger
=
get_logger
(
__file__
)
...
@@ -82,16 +79,43 @@ def hosts_add_become(hosts, adhoc_data):
...
@@ -82,16 +79,43 @@ def hosts_add_become(hosts, adhoc_data):
return
hosts
return
hosts
def
run_adhoc
(
adhoc_data
,
forks
=
10
):
def
run_adhoc
(
adhoc_data
,
**
options
):
tasks
=
adhoc_data
.
tasks
"""
:param adhoc_data: Instance of AdHocData
:param options: ansible support option, like forks ...
:return:
"""
name
=
adhoc_data
.
subject
.
name
hostname_list
=
adhoc_data
.
hosts
hostname_list
=
adhoc_data
.
hosts
adhoc_name
=
adhoc_data
.
subject
.
name
if
adhoc_data
.
run_as_admin
:
if
adhoc_data
.
run_as_admin
:
hosts
=
get_hosts_with_admin
(
adhoc_data
.
hosts
)
hosts
=
get_hosts_with_admin
(
hostname_list
)
else
:
else
:
hosts
=
get_hosts_with_run_user
(
hostname_list
,
adhoc_data
.
run_as
)
hosts
=
get_hosts_with_run_user
(
hostname_list
,
adhoc_data
.
run_as
)
hosts_add_become
(
hosts
,
adhoc_data
)
# admin user 自带become
hosts_add_become
(
hosts
,
adhoc_data
)
# admin user 自带become
runner
=
AdHocRunner
(
hosts
)
runner
=
AdHocRunner
(
hosts
)
runner
.
set_option
(
'forks'
,
forks
)
for
k
,
v
in
options
:
runner
.
set_option
(
k
,
v
)
record
=
AdHocRunHistory
(
adhoc
=
adhoc_data
)
time_start
=
time
.
time
()
try
:
result
=
runner
.
run
(
adhoc_data
.
tasks
,
adhoc_data
.
pattern
,
name
)
record
.
is_finished
=
True
if
result
.
results_summary
.
get
(
'dark'
):
record
.
is_success
=
False
else
:
record
.
is_success
=
True
record
.
result
=
result
.
results_raw
record
.
summary
=
result
.
results_summary
return
result
except
AnsibleError
as
e
:
logger
.
error
(
"Failed run adhoc {}, {}"
.
format
(
name
,
e
))
raise
finally
:
record
.
date_finished
=
timezone
.
now
()
record
.
timedelta
=
time
.
time
()
-
time_start
record
.
save
()
apps/perms/models.py
View file @
18fd04d6
from
__future__
import
unicode_literals
,
absolute_import
import
functools
import
uuid
import
uuid
from
django.db
import
models
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils
import
timezone
from
django.utils
import
timezone
from
django.db.models.signals
import
m2m_changed
from
users.models
import
User
,
UserGroup
from
assets.models
import
Asset
,
AssetGroup
,
SystemUser
from
common.utils
import
date_expired_default
,
combine_seq
from
common.utils
import
date_expired_default
,
combine_seq
class
AssetPermission
(
models
.
Model
):
class
AssetPermission
(
models
.
Model
):
from
users.models
import
User
,
UserGroup
from
assets.models
import
Asset
,
AssetGroup
,
SystemUser
# PRIVATE_FOR_CHOICE = (
# PRIVATE_FOR_CHOICE = (
# ('N', 'None'),
# ('N', 'None'),
# ('U', 'user'),
# ('U', 'user'),
...
...
apps/users/models/authentication.py
View file @
18fd04d6
...
@@ -6,7 +6,7 @@ import uuid
...
@@ -6,7 +6,7 @@ import uuid
from
django.db
import
models
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
rest_framework.authtoken.models
import
Token
from
rest_framework.authtoken.models
import
Token
from
.
import
User
from
.
user
import
User
__all__
=
[
'AccessKey'
,
'PrivateToken'
,
'LoginLog'
]
__all__
=
[
'AccessKey'
,
'PrivateToken'
,
'LoginLog'
]
...
...
apps/users/models/user.py
View file @
18fd04d6
...
@@ -14,7 +14,7 @@ from django.utils.translation import ugettext_lazy as _
...
@@ -14,7 +14,7 @@ from django.utils.translation import ugettext_lazy as _
from
django.utils
import
timezone
from
django.utils
import
timezone
from
django.shortcuts
import
reverse
from
django.shortcuts
import
reverse
from
.
import
UserGroup
from
.
group
import
UserGroup
from
common.utils
import
signer
,
date_expired_default
from
common.utils
import
signer
,
date_expired_default
...
...
apps/users/models/utils.py
View file @
18fd04d6
...
@@ -2,7 +2,8 @@
...
@@ -2,7 +2,8 @@
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
from
.
import
User
,
UserGroup
from
.user
import
User
from
.group
import
UserGroup
def
init_model
():
def
init_model
():
...
...
apps/users/tests/base.py
deleted
100644 → 0
View file @
27a1849b
# ~*~ coding: utf-8 ~*~
from
random
import
choice
import
forgery_py
from
users.models
import
User
,
UserGroup
,
init_all_models
def
gen_username
():
return
forgery_py
.
internet
.
user_name
(
True
)
def
gen_email
():
return
forgery_py
.
internet
.
email_address
()
def
gen_name
():
return
forgery_py
.
name
.
full_name
()
def
get_role
():
role
=
choice
(
dict
(
User
.
ROLE_CHOICES
)
.
keys
())
return
role
\ No newline at end of file
apps/users/tests/test_models.py
deleted
100644 → 0
View file @
27a1849b
# ~*~ coding: utf-8 ~*~
from
django.utils
import
timezone
from
django.shortcuts
import
reverse
from
django.test
import
TestCase
,
TransactionTestCase
from
django.db
import
IntegrityError
from
users.models
import
User
,
UserGroup
,
init_all_models
from
django.contrib.auth.models
import
Permission
from
.base
import
gen_name
,
gen_username
,
gen_email
,
get_role
class
UserModelTest
(
TransactionTestCase
):
def
setUp
(
self
):
init_all_models
()
# 创建一个用户用于测试
role
=
get_role
()
user
=
User
(
name
=
'test'
,
username
=
'test'
,
email
=
'test@email.org'
,
role
=
role
)
user
.
save
()
def
test_initial
(
self
):
self
.
assertEqual
(
User
.
objects
.
all
()
.
count
(),
2
)
@property
def
role
(
self
):
return
get_role
()
# 创建一个姓名一致的用户, 应该创建成功
def
test_user_name_duplicate
(
self
):
user1
=
User
(
name
=
'test'
,
username
=
gen_username
(),
password_raw
=
gen_username
(),
email
=
gen_email
())
try
:
user1
.
save
()
user1
.
delete
()
except
IntegrityError
:
self
.
assertTrue
(
0
,
'Duplicate <name> not allowed.'
)
# 创建一个用户名一致的用户, 应该创建不成功
def
test_user_username_duplicate
(
self
):
user2
=
User
(
username
=
'test'
,
email
=
gen_email
(),
role
=
self
.
role
)
with
self
.
assertRaises
(
IntegrityError
):
user2
.
save
()
# 创建一个Email一致的用户,应该创建不成功
def
test_user_email_duplicate
(
self
):
user3
=
User
(
username
=
gen_username
(),
email
=
'test@email.org'
,
role
=
self
.
role
)
with
self
.
assertRaises
(
IntegrityError
):
user3
.
save
()
# 用户过期测试
def
test_user_was_expired
(
self
):
date
=
timezone
.
now
()
-
timezone
.
timedelta
(
days
=
1
)
user
=
User
(
name
=
gen_name
(),
username
=
gen_username
(),
email
=
gen_email
(),
role
=
self
.
role
,
date_expired
=
date
)
self
.
assertTrue
(
user
.
is_expired
)
# 测试用户默认会输入All用户组
def
test_user_with_default_group
(
self
):
role
=
get_role
()
user
=
User
(
username
=
gen_username
(),
email
=
gen_email
(),
role
=
role
)
user
.
save
()
self
.
assertEqual
(
user
.
groups
.
count
(),
1
)
self
.
assertEqual
(
user
.
groups
.
first
()
.
name
,
'Default'
)
def
test_user_password_authenticated
(
self
):
password
=
gen_username
()
*
3
user
=
User
(
username
=
gen_username
(),
password_raw
=
password
,
role
=
self
.
role
)
user
.
save
()
self
.
assertTrue
(
user
.
check_password
(
password
))
self
.
assertFalse
(
user
.
check_password
(
password
*
2
))
def
test_user_reset_password
(
self
):
user
=
User
.
objects
.
first
()
token
=
User
.
generate_reset_token
(
user
.
email
)
new_password
=
gen_username
()
User
.
reset_password
(
token
,
new_password
)
user_
=
User
.
objects
.
get
(
id
=
user
.
id
)
self
.
assertTrue
(
user_
.
check_password
(
new_password
))
def
tearDown
(
self
):
User
.
objects
.
all
()
.
delete
()
UserGroup
.
objects
.
all
()
.
delete
()
class
UserGroupModelTestCase
(
TransactionTestCase
):
pass
apps/users/tests/test_views.py
deleted
100644 → 0
View file @
27a1849b
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from
users.models
import
User
,
UserGroup
,
init_all_models
from
django.shortcuts
import
reverse
from
django.test
import
TestCase
,
Client
,
TransactionTestCase
from
.base
import
gen_username
,
gen_name
,
gen_email
,
get_role
class
UserListViewTests
(
TransactionTestCase
):
def
setUp
(
self
):
init_all_models
()
self
.
client
.
login
(
username
=
'admin'
,
password
=
'admin'
)
def
test_a_new_user_in_list
(
self
):
username
=
gen_username
()
user
=
User
(
username
=
username
,
email
=
gen_email
(),
role
=
get_role
())
user
.
save
()
response
=
self
.
client
.
get
(
reverse
(
'users:user-list'
))
self
.
assertContains
(
response
,
username
)
def
test_list_view_with_admin_user
(
self
):
response
=
self
.
client
.
get
(
reverse
(
'users:user-list'
))
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertContains
(
response
,
'Admin'
)
self
.
assertEqual
(
response
.
context
[
'user_list'
]
.
count
(),
User
.
objects
.
all
()
.
count
())
def
test_pagination
(
self
):
User
.
generate_fake
(
count
=
20
)
response
=
self
.
client
.
get
(
reverse
(
'users:user-list'
))
self
.
assertEqual
(
response
.
context
[
'is_paginated'
],
True
)
def
tearDown
(
self
):
self
.
client
.
logout
()
class
UserAddTests
(
TestCase
):
def
setUp
(
self
):
init_all_models
()
self
.
client
.
login
(
username
=
'admin'
,
password
=
'admin'
)
def
test_add_a_new_user
(
self
):
username
=
gen_username
()
data
=
{
'username'
:
username
,
'comment'
:
''
,
'name'
:
gen_name
(),
'email'
:
gen_email
(),
'groups'
:
[
UserGroup
.
objects
.
first
()
.
id
,
],
'role'
:
get_role
(),
'date_expired'
:
'2086-08-06 19:12:22'
,
}
response
=
self
.
client
.
post
(
reverse
(
'users:user-create'
),
data
)
self
.
assertEqual
(
response
.
status_code
,
302
)
self
.
assertEqual
(
response
[
'location'
],
reverse
(
'users:user-list'
))
response
=
self
.
client
.
get
(
reverse
(
'users:user-list'
))
self
.
assertContains
(
response
,
username
)
def
tearDown
(
self
):
self
.
client
.
logout
()
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