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
a822f667
Commit
a822f667
authored
8 years ago
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Fixture] 完成用户推送task
parent
c234b5b2
master
auditor_jym
audits
dev
dev_beta
dev_beta_db
gengmei
lagacy-0.4.0
node_service
password
rbac
restrict_access
test
v52
wph
1.5.2
1.5.1
1.5.0
1.4.10
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.3
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.1.1
1.1.0
1.0.0
v1.4.10
v1.4.7
v1.4.4
No related merge requests found
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
274 additions
and
314 deletions
+274
-314
forms.py
apps/assets/forms.py
+36
-33
asset.py
apps/assets/models/asset.py
+1
-1
user.py
apps/assets/models/user.py
+18
-4
_system_user.html
apps/assets/templates/assets/_system_user.html
+13
-10
system_user_create.html
apps/assets/templates/assets/system_user_create.html
+7
-0
system_user_update.html
apps/assets/templates/assets/system_user_update.html
+15
-0
utils.py
apps/assets/utils.py
+2
-0
views.py
apps/assets/views.py
+7
-2
utils.py
apps/common/utils.py
+9
-0
models.py
apps/ops/models.py
+31
-0
__init__.py
apps/ops/models/__init__.py
+0
-4
ansible.py
apps/ops/models/ansible.py
+0
-0
task.py
apps/ops/models/task.py
+0
-32
utils.py
apps/ops/models/utils.py
+0
-12
tasks.py
apps/ops/tasks.py
+87
-0
__init__.py
apps/ops/tasks/__init__.py
+0
-2
_celery_tasks.py
apps/ops/tasks/_celery_tasks.py
+0
-48
taskers.py
apps/ops/tasks/taskers.py
+0
-126
view_urls.py
apps/ops/urls/view_urls.py
+2
-4
runner.py
apps/ops/utils/runner.py
+13
-5
views.py
apps/ops/views.py
+3
-21
hands.py
apps/perms/hands.py
+0
-5
asset_permission_create_update.html
...perms/templates/perms/asset_permission_create_update.html
+1
-1
utils.py
apps/perms/utils.py
+20
-3
views.py
apps/perms/views.py
+6
-0
requirements.txt
requirements/requirements.txt
+1
-0
run_server.py
run_server.py
+2
-1
No files found.
apps/assets/forms.py
View file @
a822f667
...
@@ -3,7 +3,10 @@ from django import forms
...
@@ -3,7 +3,10 @@ from django import forms
from
django.utils.translation
import
gettext_lazy
as
_
from
django.utils.translation
import
gettext_lazy
as
_
from
.models
import
IDC
,
Asset
,
AssetGroup
,
AdminUser
,
SystemUser
,
Tag
from
.models
import
IDC
,
Asset
,
AssetGroup
,
AdminUser
,
SystemUser
,
Tag
from
common.utils
import
validate_ssh_private_key
,
ssh_pubkey_gen
from
common.utils
import
validate_ssh_private_key
,
ssh_pubkey_gen
,
ssh_key_gen
,
get_logger
logger
=
get_logger
(
__file__
)
class
AssetCreateForm
(
forms
.
ModelForm
):
class
AssetCreateForm
(
forms
.
ModelForm
):
...
@@ -207,59 +210,59 @@ class SystemUserForm(forms.ModelForm):
...
@@ -207,59 +210,59 @@ class SystemUserForm(forms.ModelForm):
# Admin user assets define, let user select, save it in form not in view
# Admin user assets define, let user select, save it in form not in view
auto_generate_key
=
forms
.
BooleanField
(
initial
=
True
,
required
=
False
)
auto_generate_key
=
forms
.
BooleanField
(
initial
=
True
,
required
=
False
)
# Form field name can not start with `_`, so redefine it,
# Form field name can not start with `_`, so redefine it,
password
=
forms
.
CharField
(
widget
=
forms
.
PasswordInput
,
max_length
=
100
,
min_length
=
8
,
strip
=
True
)
password
=
forms
.
CharField
(
widget
=
forms
.
PasswordInput
,
required
=
False
,
max_length
=
100
,
min_length
=
8
,
strip
=
True
)
# Need use upload private key file except paste private key content
# Need use upload private key file except paste private key content
private_key_file
=
forms
.
FileField
(
required
=
False
)
private_key_file
=
forms
.
FileField
(
required
=
False
)
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
# When update a admin user instance, initial it
if
kwargs
.
get
(
'instance'
):
initial
=
kwargs
.
get
(
'initial'
,
{})
initial
[
'assets'
]
=
kwargs
[
'instance'
]
.
assets
.
all
()
initial
[
'asset_groups'
]
=
kwargs
[
'instance'
]
.
asset_groups
.
all
()
super
(
SystemUserForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
super
(
SystemUserForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
def
save
(
self
,
commit
=
True
):
def
save
(
self
,
commit
=
True
):
# Because we define custom field, so we need rewrite :method: `save`
# Because we define custom field, so we need rewrite :method: `save`
system_user
=
super
(
SystemUserForm
,
self
)
.
save
(
commit
=
commit
)
system_user
=
super
(
SystemUserForm
,
self
)
.
save
(
commit
=
commit
)
password
=
self
.
cleaned_data
[
'password'
]
password
=
self
.
cleaned_data
[
'password'
]
private_key_file
=
self
.
cleaned_data
[
'private_key_file'
]
private_key_file
=
self
.
cleaned_data
.
get
(
'private_key_file'
)
if
system_user
.
auth_method
==
'P'
:
if
system_user
.
auth_method
==
'P'
:
if
password
:
if
password
:
system_user
.
password
=
password
system_user
.
password
=
password
print
(
password
)
elif
system_user
.
auth_method
==
'K'
:
# Todo: Validate private key file, and generate public key
if
self
.
cleaned_data
[
'auto_generate_key'
]:
# Todo: Auto generate private key and public key
private_key
,
public_key
=
ssh_key_gen
(
username
=
system_user
.
name
)
if
private_key_file
:
logger
.
info
(
'Generate private key and public key'
)
system_user
.
private_key
=
private_key_file
.
read
()
.
strip
()
else
:
private_key
=
private_key_file
.
read
()
.
strip
()
public_key
=
ssh_pubkey_gen
(
private_key
=
private_key
)
system_user
.
private_key
=
private_key
system_user
.
public_key
=
public_key
system_user
.
save
()
system_user
.
save
()
return
self
.
instance
return
self
.
instance
# Todo: check valid
def
clean_private_key_file
(
self
):
# def clean_private_key_file(self):
if
self
.
data
[
'auth_method'
]
==
'K'
and
\
# if not self.cleaned_data['auto_generate_key']:
not
self
.
cleaned_data
[
'auto_generate_key'
]:
# if not self.cleaned_data['private_key_file']:
if
not
self
.
cleaned_data
[
'private_key_file'
]:
# raise forms.ValidationError(_('Private key required'))
raise
forms
.
ValidationError
(
_
(
'Private key required'
))
else
:
# def clean_password(self):
key_string
=
self
.
cleaned_data
[
'private_key_file'
]
.
read
()
# if self.cleaned_data['auth_method'] == 'P':
self
.
cleaned_data
[
'private_key_file'
]
.
seek
(
0
)
# if not self.cleaned_data['password']:
if
not
validate_ssh_private_key
(
key_string
):
# raise forms.ValidationError(_('Password required'))
raise
forms
.
ValidationError
(
_
(
'Private key invalid'
))
# return self.cleaned_data['password']
return
self
.
cleaned_data
[
'private_key_file'
]
# def clean(self):
def
clean_password
(
self
):
# password = self.cleaned_data['password']
if
self
.
data
[
'auth_method'
]
==
'P'
:
# private_key_file = self.cleaned_data.get('private_key_file', '')
if
not
self
.
cleaned_data
.
get
(
'password'
):
#
raise
forms
.
ValidationError
(
_
(
'Password required'
))
# if not (password or private_key_file):
return
self
.
cleaned_data
[
'password'
]
# raise forms.ValidationError(_('Password and private key file must be input one'))
class
Meta
:
class
Meta
:
model
=
SystemUser
model
=
SystemUser
fields
=
[
fields
=
[
'name'
,
'username'
,
'protocol'
,
'auto_generate_key'
,
'password'
,
'private_key_file'
,
'auth_method'
,
'name'
,
'username'
,
'protocol'
,
'auto_generate_key'
,
'password'
,
'auto_push'
,
'sudo'
,
'comment'
,
'shell'
,
'home'
,
'uid'
,
'private_key_file'
,
'auth_method'
,
'auto_push'
,
'sudo'
,
'comment'
,
'shell'
,
'home'
,
'uid'
,
]
]
widgets
=
{
widgets
=
{
'name'
:
forms
.
TextInput
(
attrs
=
{
'placeholder'
:
_
(
'Name'
)}),
'name'
:
forms
.
TextInput
(
attrs
=
{
'placeholder'
:
_
(
'Name'
)}),
...
...
This diff is collapsed.
Click to expand it.
apps/assets/models/asset.py
View file @
a822f667
...
@@ -71,7 +71,7 @@ class Asset(models.Model):
...
@@ -71,7 +71,7 @@ class Asset(models.Model):
tags
=
models
.
ManyToManyField
(
'Tag'
,
related_name
=
'assets'
,
blank
=
True
,
verbose_name
=
_
(
'Tags'
))
tags
=
models
.
ManyToManyField
(
'Tag'
,
related_name
=
'assets'
,
blank
=
True
,
verbose_name
=
_
(
'Tags'
))
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
'
%
(ip)
s:
%(port)
s'
%
{
'ip'
:
self
.
ip
,
'port'
:
self
.
port
}
return
'
%
s <
%
s:
%
s>'
%
(
self
.
hostname
,
self
.
ip
,
self
.
port
)
__str__
=
__unicode__
__str__
=
__unicode__
...
...
This diff is collapsed.
Click to expand it.
apps/assets/models/user.py
View file @
a822f667
...
@@ -116,14 +116,13 @@ class SystemUser(models.Model):
...
@@ -116,14 +116,13 @@ class SystemUser(models.Model):
)
)
name
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
_
(
'Name'
))
name
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
_
(
'Name'
))
username
=
models
.
CharField
(
max_length
=
16
,
verbose_name
=
_
(
'Username'
))
username
=
models
.
CharField
(
max_length
=
16
,
verbose_name
=
_
(
'Username'
))
_password
=
models
.
CharField
(
max_length
=
256
,
blank
=
True
,
verbose_name
=
_
(
'Password'
))
_password
=
models
.
CharField
(
max_length
=
256
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'Password'
))
protocol
=
models
.
CharField
(
max_length
=
16
,
choices
=
PROTOCOL_CHOICES
,
default
=
'ssh'
,
verbose_name
=
_
(
'Protocol'
))
protocol
=
models
.
CharField
(
max_length
=
16
,
choices
=
PROTOCOL_CHOICES
,
default
=
'ssh'
,
verbose_name
=
_
(
'Protocol'
))
_private_key
=
models
.
CharField
(
max_length
=
4096
,
blank
=
True
,
verbose_name
=
_
(
'SSH private key'
))
_private_key
=
models
.
CharField
(
max_length
=
4096
,
blank
=
True
,
verbose_name
=
_
(
'SSH private key'
))
_public_key
=
models
.
CharField
(
max_length
=
4096
,
blank
=
True
,
verbose_name
=
_
(
'SSH public key'
))
_public_key
=
models
.
CharField
(
max_length
=
4096
,
blank
=
True
,
verbose_name
=
_
(
'SSH public key'
))
auth_method
=
models
.
CharField
(
choices
=
AUTH_METHOD_CHOICES
,
default
=
'K'
,
auth_method
=
models
.
CharField
(
choices
=
AUTH_METHOD_CHOICES
,
default
=
'K'
,
max_length
=
1
,
verbose_name
=
_
(
'Auth method'
))
max_length
=
1
,
verbose_name
=
_
(
'Auth method'
))
auto_push
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'Auto push'
))
auto_push
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'Auto push'
))
auto_update
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'Auto update pass/key'
))
sudo
=
models
.
TextField
(
max_length
=
4096
,
default
=
'/user/bin/whoami'
,
verbose_name
=
_
(
'Sudo'
))
sudo
=
models
.
TextField
(
max_length
=
4096
,
default
=
'/user/bin/whoami'
,
verbose_name
=
_
(
'Sudo'
))
shell
=
models
.
CharField
(
max_length
=
64
,
default
=
'/bin/bash'
,
verbose_name
=
_
(
'Shell'
))
shell
=
models
.
CharField
(
max_length
=
64
,
default
=
'/bin/bash'
,
verbose_name
=
_
(
'Shell'
))
home
=
models
.
CharField
(
max_length
=
64
,
blank
=
True
,
verbose_name
=
_
(
'Home'
))
home
=
models
.
CharField
(
max_length
=
64
,
blank
=
True
,
verbose_name
=
_
(
'Home'
))
...
@@ -137,7 +136,9 @@ class SystemUser(models.Model):
...
@@ -137,7 +136,9 @@ class SystemUser(models.Model):
@property
@property
def
password
(
self
):
def
password
(
self
):
return
signer
.
unsign
(
self
.
_password
)
if
self
.
_password
:
return
signer
.
unsign
(
self
.
_password
)
return
None
@password.setter
@password.setter
def
password
(
self
,
password_raw
):
def
password
(
self
,
password_raw
):
...
@@ -145,7 +146,9 @@ class SystemUser(models.Model):
...
@@ -145,7 +146,9 @@ class SystemUser(models.Model):
@property
@property
def
private_key
(
self
):
def
private_key
(
self
):
return
signer
.
unsign
(
self
.
_private_key
)
if
self
.
_private_key
:
return
signer
.
unsign
(
self
.
_private_key
)
return
None
@private_key.setter
@private_key.setter
def
private_key
(
self
,
private_key_raw
):
def
private_key
(
self
,
private_key_raw
):
...
@@ -174,6 +177,17 @@ class SystemUser(models.Model):
...
@@ -174,6 +177,17 @@ class SystemUser(models.Model):
assets
=
set
(
self
.
assets
.
all
())
|
self
.
get_assets_inherit_from_asset_groups
()
assets
=
set
(
self
.
assets
.
all
())
|
self
.
get_assets_inherit_from_asset_groups
()
return
list
(
assets
)
return
list
(
assets
)
def
_to_secret_json
(
self
):
"""Push system user use it"""
return
{
'name'
:
self
.
name
,
'username'
:
self
.
username
,
'shell'
:
self
.
shell
,
'sudo'
:
self
.
sudo
,
'password'
:
self
.
password
,
'public_key'
:
self
.
public_key
}
@property
@property
def
assets_amount
(
self
):
def
assets_amount
(
self
):
return
self
.
assets
.
count
()
return
self
.
assets
.
count
()
...
...
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/
system_user_create_update
.html
→
apps/assets/templates/assets/
_system_user
.html
View file @
a822f667
...
@@ -34,14 +34,20 @@
...
@@ -34,14 +34,20 @@
{% endif %}
{% endif %}
<form
enctype=
"multipart/form-data"
method=
"post"
class=
"form-horizontal"
action=
""
>
<form
enctype=
"multipart/form-data"
method=
"post"
class=
"form-horizontal"
action=
""
>
{% csrf_token %}
{% csrf_token %}
{% if form.non_field_errors %}
<div
class=
"alert alert-danger"
>
{{ form.non_field_errors }}
</div>
{% endif %}
<h3>
{% trans 'Basic' %}
</h3>
<h3>
{% trans 'Basic' %}
</h3>
{{ form.name|bootstrap_horizontal }}
{{ form.name|bootstrap_horizontal }}
{{ form.username|bootstrap_horizontal }}
{{ form.username|bootstrap_horizontal }}
{{ form.protocol|bootstrap_horizontal }}
{{ form.protocol|bootstrap_horizontal }}
<h3>
{% trans 'Auth' %}
</h3>
<h3>
{% trans 'Auth' %}
</h3>
{{ form.auth_method|bootstrap_horizontal }}
{{ form.auth_method|bootstrap_horizontal }}
{% block auth %}
<div
class=
"password-auth hidden"
>
<div
class=
"password-auth hidden"
>
{{ form.password|bootstrap_horizontal }}
{{ form.password|bootstrap_horizontal }}
</div>
</div>
<div
class=
"public-key-auth"
>
<div
class=
"public-key-auth"
>
<div
class=
"form-group"
>
<div
class=
"form-group"
>
...
@@ -54,6 +60,7 @@
...
@@ -54,6 +60,7 @@
{{ form.private_key_file|bootstrap_horizontal }}
{{ form.private_key_file|bootstrap_horizontal }}
</div>
</div>
</div>
</div>
{% endblock %}
<div
class=
"form-group"
>
<div
class=
"form-group"
>
<label
for=
"{{ form.as_push.id_for_label }}"
class=
"col-sm-2 control-label"
>
{% trans 'Auto push' %}
</label>
<label
for=
"{{ form.as_push.id_for_label }}"
class=
"col-sm-2 control-label"
>
{% trans 'Auto push' %}
</label>
<div
class=
"col-sm-8"
>
<div
class=
"col-sm-8"
>
...
@@ -88,16 +95,19 @@
...
@@ -88,16 +95,19 @@
$
(
'.password-auth'
).
removeClass
(
'hidden'
);
$
(
'.password-auth'
).
removeClass
(
'hidden'
);
$
(
'.public-key-auth'
).
addClass
(
'hidden'
);
$
(
'.public-key-auth'
).
addClass
(
'hidden'
);
$
(
'#'
+
'{{ form.password.id_for_label }}'
).
attr
(
'required'
,
'required'
);
$
(
'#'
+
'{{ form.password.id_for_label }}'
).
attr
(
'required'
,
'required'
);
$
(
'#'
+
'{{ form.password.id_for_label }}'
).
removeAttr
(
'disabled'
);
}
else
if
(
$
(
auth_method
).
val
()
==
'K'
)
{
}
else
if
(
$
(
auth_method
).
val
()
==
'K'
)
{
$
(
'.password-auth'
).
addClass
(
'hidden'
);
$
(
'.password-auth'
).
addClass
(
'hidden'
);
$
(
'.public-key-auth'
).
removeClass
(
'hidden'
);
$
(
'.public-key-auth'
).
removeClass
(
'hidden'
);
$
(
'#'
+
'{{ form.password.id_for_label }}'
).
removeAttr
(
'required'
);
$
(
'#'
+
'{{ form.password.id_for_label }}'
).
attr
(
'disabled'
,
'disabled'
);
if
(
$
(
auto_generate_key
).
prop
(
'checked'
)){
if
(
$
(
auto_generate_key
).
prop
(
'checked'
)){
$
(
'#'
+
'{{ form.private_key_file.id_for_label }}'
).
closest
(
'.form-group'
).
addClass
(
'hidden'
);
$
(
'#'
+
'{{ form.private_key_file.id_for_label }}'
).
closest
(
'.form-group'
).
addClass
(
'hidden'
);
}
else
{
}
else
{
$
(
'#'
+
'{{ form.private_key_file.id_for_label }}'
).
closest
(
'.form-group'
).
removeClass
(
'hidden'
);
$
(
'#'
+
'{{ form.private_key_file.id_for_label }}'
).
closest
(
'.form-group'
).
removeClass
(
'hidden'
);
{
#
$
(
'#'
+
'{{ form.private_key_file.id_for_label }}'
).
attr
(
'required'
,
'required'
);
#
}
$
(
'#'
+
'{{ form.private_key_file.id_for_label }}'
).
closest
(
'.form-group input'
).
attr
(
'required'
,
'required'
);
}
}
}
}
}
}
...
@@ -110,14 +120,8 @@
...
@@ -110,14 +120,8 @@
$
(
auto_generate_key
).
change
(
function
()
{
$
(
auto_generate_key
).
change
(
function
()
{
authMethodDisplay
();
authMethodDisplay
();
});
});
})
if
(
$
(
'#'
+
'{{ form.protocol.id_for_label }}'
).
val
()
==
'telnet'
)
{
$
(
'#'
+
'{{ form.auto_generate_key.id_for_label }}'
).
closest
(
'.form-group'
).
remove
();
$
(
'#'
+
'{{ form.private_key_file.id_for_label }}'
).
closest
(
'.form-group'
).
remove
();
$
(
'#'
+
'{{ form.auto_push.id_for_label }}'
).
closest
(
'.form-group'
).
remove
();
$
(
'#'
+
'{{ form.auto_update.id_for_label }}'
).
closest
(
'.form-group'
).
remove
();
}
})
</script>
</script>
{% endblock %}
{% endblock %}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/system_user_create.html
0 → 100644
View file @
a822f667
{% extends 'assets/_system_user.html' %}
{% load i18n %}
{% load static %}
{% block auth %}
{{ block.super }}
{% endblock %}
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/system_user_update.html
0 → 100644
View file @
a822f667
{% extends 'assets/_system_user.html' %}
{% load i18n %}
{% load static %}
{% load bootstrap %}
{% block auth %}
<div
class=
"password-auth hidden"
>
{{ form.password|bootstrap_horizontal }}
</div>
<div
class=
"public-key-auth"
>
<div>
{{ form.private_key_file|bootstrap_horizontal }}
</div>
</div>
{% endblock %}
This diff is collapsed.
Click to expand it.
apps/assets/utils.py
View file @
a822f667
...
@@ -4,6 +4,7 @@ from rest_framework import serializers
...
@@ -4,6 +4,7 @@ from rest_framework import serializers
from
models
import
Tag
from
models
import
Tag
from
django.views.generic.edit
import
CreateView
from
django.views.generic.edit
import
CreateView
class
CreateAssetTagsMiXin
(
CreateView
):
class
CreateAssetTagsMiXin
(
CreateView
):
def
get_form_kwargs
(
self
):
def
get_form_kwargs
(
self
):
tags_list
=
self
.
request
.
POST
.
getlist
(
'tags'
)
tags_list
=
self
.
request
.
POST
.
getlist
(
'tags'
)
...
@@ -30,6 +31,7 @@ class CreateAssetTagsMiXin(CreateView):
...
@@ -30,6 +31,7 @@ class CreateAssetTagsMiXin(CreateView):
})
})
return
kwargs
return
kwargs
class
UpdateAssetTagsMiXin
(
CreateAssetTagsMiXin
):
class
UpdateAssetTagsMiXin
(
CreateAssetTagsMiXin
):
def
get_form_kwargs
(
self
):
def
get_form_kwargs
(
self
):
kwargs
=
super
(
UpdateAssetTagsMiXin
,
self
)
.
get_form_kwargs
()
kwargs
=
super
(
UpdateAssetTagsMiXin
,
self
)
.
get_form_kwargs
()
...
...
This diff is collapsed.
Click to expand it.
apps/assets/views.py
View file @
a822f667
...
@@ -9,6 +9,7 @@ from openpyxl import load_workbook
...
@@ -9,6 +9,7 @@ from openpyxl import load_workbook
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
django.conf
import
settings
from
django.conf
import
settings
from
django.db.models
import
Q
from
django.db.models
import
Q
from
django.db
import
transaction
from
django.db
import
IntegrityError
from
django.db
import
IntegrityError
from
django.views.generic
import
TemplateView
,
ListView
,
View
from
django.views.generic
import
TemplateView
,
ListView
,
View
from
django.views.generic.edit
import
CreateView
,
DeleteView
,
FormView
,
UpdateView
from
django.views.generic.edit
import
CreateView
,
DeleteView
,
FormView
,
UpdateView
...
@@ -521,9 +522,13 @@ class SystemUserListView(AdminUserRequiredMixin, TemplateView):
...
@@ -521,9 +522,13 @@ class SystemUserListView(AdminUserRequiredMixin, TemplateView):
class
SystemUserCreateView
(
AdminUserRequiredMixin
,
SuccessMessageMixin
,
CreateView
):
class
SystemUserCreateView
(
AdminUserRequiredMixin
,
SuccessMessageMixin
,
CreateView
):
model
=
SystemUser
model
=
SystemUser
form_class
=
forms
.
SystemUserForm
form_class
=
forms
.
SystemUserForm
template_name
=
'assets/system_user_create
_update
.html'
template_name
=
'assets/system_user_create.html'
success_url
=
reverse_lazy
(
'assets:system-user-list'
)
success_url
=
reverse_lazy
(
'assets:system-user-list'
)
@transaction.atomic
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
return
super
(
SystemUserCreateView
,
self
)
.
post
(
request
,
*
args
,
**
kwargs
)
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
context
=
{
'app'
:
_
(
'Assets'
),
'app'
:
_
(
'Assets'
),
...
@@ -549,7 +554,7 @@ class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateVi
...
@@ -549,7 +554,7 @@ class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateVi
class
SystemUserUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
class
SystemUserUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
model
=
SystemUser
model
=
SystemUser
form_class
=
forms
.
SystemUserForm
form_class
=
forms
.
SystemUserForm
template_name
=
'assets/system_user_
create_
update.html'
template_name
=
'assets/system_user_update.html'
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
context
=
{
...
...
This diff is collapsed.
Click to expand it.
apps/common/utils.py
View file @
a822f667
...
@@ -16,6 +16,7 @@ import calendar
...
@@ -16,6 +16,7 @@ import calendar
import
threading
import
threading
import
paramiko
import
paramiko
from
passlib.hash
import
sha512_crypt
import
sshpubkeys
import
sshpubkeys
from
itsdangerous
import
TimedJSONWebSignatureSerializer
,
JSONWebSignatureSerializer
,
\
from
itsdangerous
import
TimedJSONWebSignatureSerializer
,
JSONWebSignatureSerializer
,
\
BadSignature
,
SignatureExpired
BadSignature
,
SignatureExpired
...
@@ -322,4 +323,11 @@ def make_signature(access_key_secret, date=None):
...
@@ -322,4 +323,11 @@ def make_signature(access_key_secret, date=None):
return
content_md5
(
data
)
return
content_md5
(
data
)
def
encrypt_password
(
password
):
from
passlib.hash
import
sha512_crypt
if
password
:
return
sha512_crypt
.
using
(
rounds
=
5000
)
.
hash
(
password
)
return
None
signer
=
Signer
()
signer
=
Signer
()
\ No newline at end of file
This diff is collapsed.
Click to expand it.
apps/ops/models.py
0 → 100644
View file @
a822f667
# ~*~ coding: utf-8 ~*~
from
__future__
import
unicode_literals
,
absolute_import
import
logging
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
__all__
=
[
"TaskRecord"
]
logger
=
logging
.
getLogger
(
__name__
)
class
TaskRecord
(
models
.
Model
):
uuid
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'UUID'
),
primary_key
=
True
)
name
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
verbose_name
=
_
(
'Name'
))
date_start
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'Start time'
))
date_finished
=
models
.
DateTimeField
(
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'End time'
))
is_finished
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
'Is finished'
))
is_success
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
'Is success'
))
assets
=
models
.
TextField
(
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'Assets'
))
result
=
models
.
TextField
(
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'Task result'
))
def
__unicode__
(
self
):
return
"
%
s"
%
self
.
uuid
@property
def
total_assets
(
self
):
return
self
.
assets
.
split
(
','
)
This diff is collapsed.
Click to expand it.
apps/ops/models/__init__.py
deleted
100644 → 0
View file @
c234b5b2
from
ansible
import
*
from
utils
import
*
from
task
import
*
This diff is collapsed.
Click to expand it.
apps/ops/models/ansible.py
deleted
100644 → 0
View file @
c234b5b2
This diff is collapsed.
Click to expand it.
apps/ops/models/task.py
deleted
100644 → 0
View file @
c234b5b2
# ~*~ coding: utf-8 ~*~
from
__future__
import
unicode_literals
,
absolute_import
import
logging
from
uuid
import
uuid4
from
assets.models
import
Asset
from
ops.models
import
TaskRecord
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
__all__
=
[
"Task"
]
class
Task
(
models
.
Model
):
"""
Ansible 的Task
"""
name
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'Task name'
))
module_name
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'Task module'
))
module_args
=
models
.
CharField
(
max_length
=
512
,
blank
=
True
,
verbose_name
=
_
(
"Module args"
))
def
__unicode__
(
self
):
return
"
%
s"
%
self
.
name
class
Play
(
models
.
Model
):
"""
Playbook 模板, 定义好Template后生成 Playbook
"""
This diff is collapsed.
Click to expand it.
apps/ops/models/utils.py
deleted
100644 → 0
View file @
c234b5b2
# ~*~ coding: utf-8 ~*~
from
__future__
import
unicode_literals
from
ansible
import
*
__all__
=
[
"generate_fake"
]
def
generate_fake
():
for
cls
in
(
TaskRecord
,
AnsiblePlay
,
AnsibleTask
,
AnsibleHostResult
):
cls
.
generate_fake
()
\ No newline at end of file
This diff is collapsed.
Click to expand it.
apps/ops/tasks.py
0 → 100644
View file @
a822f667
# coding: utf-8
from
__future__
import
absolute_import
,
unicode_literals
import
time
from
django.utils
import
timezone
from
celery
import
shared_task
from
common.utils
import
get_logger
,
encrypt_password
from
.utils.runner
import
AdHocRunner
from
.models
import
TaskRecord
logger
=
get_logger
(
__file__
)
@shared_task
(
name
=
"get_assets_hardware_info"
)
def
get_assets_hardware_info
(
self
,
assets
):
task_tuple
=
(
(
'setup'
,
''
),
)
hoc
=
AdHocRunner
(
assets
)
return
hoc
.
run
(
task_tuple
)
@shared_task
(
name
=
"asset_test_ping_check"
)
def
asset_test_ping_check
(
assets
):
task_tuple
=
(
(
'ping'
,
''
),
)
hoc
=
AdHocRunner
(
assets
)
result
=
hoc
.
run
(
task_tuple
)
return
result
[
'contacted'
]
.
keys
(),
result
[
'dark'
]
.
keys
()
@shared_task
(
bind
=
True
)
def
push_users
(
self
,
assets
,
users
):
"""
user: {
username: xxx,
shell: /bin/bash,
password: 'staf',
public_key: 'string',
sudo: '/bin/whoami,/sbin/ifconfig'
}
"""
if
isinstance
(
users
,
dict
):
users
=
[
users
]
if
isinstance
(
assets
,
dict
):
assets
=
[
assets
]
task_tuple
=
[]
for
user
in
users
:
logger
.
debug
(
'Push user: {}'
.
format
(
user
))
# 添加用户, 设置公钥, 设置sudo
task_tuple
.
extend
([
(
'user'
,
'name={} shell={} state=present password={}'
.
format
(
user
[
'username'
],
user
.
get
(
'shell'
,
'/bin/bash'
),
encrypt_password
(
user
.
get
(
'password'
,
None
)))),
(
'authorized_key'
,
"user={} state=present key='{}'"
.
format
(
user
[
'username'
],
user
[
'public_key'
])),
(
'lineinfile'
,
"name=/etc/sudoers state=present regexp='^{0} ALL=(ALL)' "
"line='{0} ALL=(ALL) NOPASSWD: {1}' "
"validate='visudo -cf
%
s'"
.
format
(
user
[
'username'
],
user
.
get
(
'sudo'
,
'/bin/whoami'
)
))
])
record
=
TaskRecord
(
name
=
'Push user'
,
uuid
=
self
.
request
.
id
,
date_start
=
timezone
.
now
(),
assets
=
','
.
join
(
asset
[
'hostname'
]
for
asset
in
assets
))
record
.
save
()
logger
.
info
(
'Runner start {0}'
.
format
(
timezone
.
now
()))
hoc
=
AdHocRunner
(
assets
)
_
=
hoc
.
run
(
task_tuple
)
logger
.
info
(
'Runner complete {0}'
.
format
(
timezone
.
now
()))
result_clean
=
hoc
.
clean_result
()
record
.
date_finished
=
timezone
.
now
()
record
.
is_finished
=
True
if
len
(
result_clean
[
'failed'
])
==
0
:
record
.
is_success
=
True
else
:
record
.
is_success
=
False
record
.
result
=
result_clean
record
.
save
()
return
result_clean
This diff is collapsed.
Click to expand it.
apps/ops/tasks/__init__.py
deleted
100644 → 0
View file @
c234b5b2
from
taskers
import
*
\ No newline at end of file
This diff is collapsed.
Click to expand it.
apps/ops/tasks/_celery_tasks.py
deleted
100644 → 0
View file @
c234b5b2
from
__future__
import
absolute_import
,
unicode_literals
from
celery
import
shared_task
from
common
import
celery_app
from
ops.utils.ansible_api
import
Options
,
ADHocRunner
@shared_task
(
name
=
"get_asset_hardware_info"
)
def
get_asset_hardware_info
(
task_name
,
task_uuid
,
*
assets
):
conf
=
Options
()
play_source
=
{
"name"
:
"Get host hardware information"
,
"hosts"
:
"default"
,
"gather_facts"
:
"no"
,
"tasks"
:
[
dict
(
action
=
dict
(
module
=
'setup'
))
]
}
hoc
=
ADHocRunner
(
conf
,
play_source
,
*
assets
)
ext_code
,
result
=
hoc
.
run
(
task_name
,
task_uuid
)
return
ext_code
,
result
@shared_task
(
name
=
"asset_test_ping_check"
)
def
asset_test_ping_check
(
task_name
,
task_uuid
,
*
assets
):
conf
=
Options
()
play_source
=
{
"name"
:
"Test host connection use ping"
,
"hosts"
:
"default"
,
"gather_facts"
:
"no"
,
"tasks"
:
[
dict
(
action
=
dict
(
module
=
'ping'
))
]
}
hoc
=
ADHocRunner
(
conf
,
play_source
,
*
assets
)
ext_code
,
result
=
hoc
.
run
(
task_name
,
task_uuid
)
return
ext_code
,
result
@shared_task
(
name
=
"add_user_to_assert"
)
def
add_user_to_asset
():
pass
@celery_app.task
(
name
=
'hello-world'
)
def
hello
():
print
(
'hello world!'
)
This diff is collapsed.
Click to expand it.
apps/ops/tasks/taskers.py
deleted
100644 → 0
View file @
c234b5b2
# ~*~ coding: utf-8 ~*~
from
__future__
import
unicode_literals
from
ops.tasks
import
_celery_tasks
from
ops.models
import
TaskRecord
from
uuid
import
uuid1
from
celery.result
import
AsyncResult
__all__
=
[
"get_result"
,
"start_get_hardware_info"
,
"start_ping_test"
,
"get_hardware_info"
,
"get_ping_test"
]
def
get_result
(
task_id
):
result
=
AsyncResult
(
task_id
)
if
result
.
ready
():
return
{
"Completed"
:
True
,
"data"
:
result
.
get
()}
else
:
return
{
"Completed"
:
False
,
"data"
:
None
}
def
__get_result_by_tasker_id
(
tasker_uuid
,
deal_method
):
tasker
=
TaskRecord
.
objects
.
get
(
uuid
=
tasker_uuid
)
total
=
tasker
.
total_hosts
total_len
=
len
(
total
)
host_results
=
[]
# 存储数据
for
play
in
tasker
.
plays
.
all
():
for
t
in
play
.
tasks
.
all
():
task
=
{
'name'
:
t
.
name
,
'uuid'
:
t
.
uuid
,
'percentage'
:
0
,
'completed'
:
{
'success'
:
{},
'failed'
:
{}}}
completed
=
[]
count
=
0
for
h
in
t
.
host_results
.
all
():
completed
.
append
(
h
.
name
)
count
+=
1
if
h
.
is_success
:
result
=
getattr
(
h
,
deal_method
)
if
result
.
get
(
'msg'
)
is
None
:
task
[
'completed'
][
'success'
][
h
.
name
]
=
result
.
get
(
'data'
)
else
:
task
[
'completed'
][
'failed'
][
h
.
name
]
=
result
.
get
(
'msg'
)
else
:
task
[
'completed'
][
'failed'
][
h
.
name
]
=
h
.
failed_msg
# 计算进度
task
[
'percentage'
]
=
float
(
count
*
100
/
total_len
)
task
[
'waited'
]
=
list
(
set
(
total
)
-
set
(
completed
))
host_results
.
append
(
task
)
return
host_results
def
start_get_hardware_info
(
*
assets
):
name
=
"Get host hardware information"
uuid
=
"tasker-"
+
uuid1
()
.
hex
_celery_tasks
.
get_asset_hardware_info
.
delay
(
name
,
uuid
,
*
assets
)
return
uuid
def
__get_hardware_info
(
tasker_uuid
):
return
__get_result_by_tasker_id
(
tasker_uuid
,
'deal_setup'
)
def
get_hardware_info
(
tasker_uuid
):
"""
:param assets: 资产列表
:return: 返回数据结构样列
{u'data': [{u'completed': {
u'failed': {u'192.168.232.135': u'Authentication failure.'},
u'success': {u'192.168.1.119': {u'cpu': u'GenuineIntel Intel Xeon E312xx (Sandy Bridge) 6
\u6838
',
u'disk': {<device_name>: <device_detail_dict>},
u'env': {<env_name>: <env_value>},
u'interface': {<interface_name>: <interface_detail_dict>},
u'mem': 3951,
u'os': u'Ubuntu 16.04(xenial)',
u'sn': u'NA'}}},
u'name': u'',
u'percentage': 100.0,
u'uuid': u'87cfedfe-ba55-44ff-bc43-e7e73b869ca1',
u'waited': []}
],
u'msg': None}
"""
try
:
return
{
"msg"
:
None
,
"data"
:
__get_hardware_info
(
tasker_uuid
)}
except
Exception
as
e
:
return
{
"msg"
:
"query data failed!,
%
s"
%
e
.
message
,
"data"
:
None
}
def
start_ping_test
(
*
assets
):
name
=
"Test host connection"
uuid
=
"tasker-"
+
uuid1
()
.
hex
_celery_tasks
.
asset_test_ping_check
.
delay
(
name
,
uuid
,
*
assets
)
return
uuid
def
__get_ping_test
(
tasker_uuid
):
return
__get_result_by_tasker_id
(
tasker_uuid
,
'deal_ping'
)
def
get_ping_test
(
tasker_uuid
):
"""
:param assets: 资产列表
:return: 返回数据结构样列
{u'data': [{u'completed': {
u'failed': {u'192.168.232.135': u'Authentication failure.'},
u'success': {u'192.168.1.119': {u'success': True}}},
u'name': u'',
u'percentage': 100.0,
u'uuid': u'3e6e0d3b-bee0-4383-b19e-bec6ba55d346',
u'waited': []}
],
u'msg': None}
"""
try
:
return
{
"msg"
:
None
,
"data"
:
__get_ping_test
(
tasker_uuid
)}
except
Exception
as
e
:
return
{
"msg"
:
"query data failed!,
%
s"
%
e
.
message
,
"data"
:
None
}
This diff is collapsed.
Click to expand it.
apps/ops/urls/view_urls.py
View file @
a822f667
...
@@ -9,8 +9,5 @@ __all__ = ["urlpatterns"]
...
@@ -9,8 +9,5 @@ __all__ = ["urlpatterns"]
urlpatterns
=
[
urlpatterns
=
[
# TResource Task url
# TResource Task url
url
(
r'^task/list$'
,
page_view
.
TaskListView
.
as_view
(),
name
=
'page-task-list'
),
url
(
r'^task/list$'
,
page_view
.
TaskListView
.
as_view
(),
name
=
'page-task-list'
),
url
(
r'^task/create$'
,
page_view
.
TaskCreateView
.
as_view
(),
name
=
'page-task-create'
),
url
(
r'^task/(?P<pk>[0-9]+)/detail$'
,
page_view
.
TaskDetailView
.
as_view
(),
name
=
'page-task-detail'
),
url
(
r'^task/(?P<pk>[0-9]+)/update$'
,
page_view
.
TaskUpdateView
.
as_view
(),
name
=
'page-task-update'
),
]
]
\ No newline at end of file
This diff is collapsed.
Click to expand it.
apps/ops/utils/runner.py
View file @
a822f667
# ~*~ coding: utf-8 ~*~
# ~*~ coding: utf-8 ~*~
from
__future__
import
unicode_literals
import
os
import
os
import
sys
from
collections
import
namedtuple
,
defaultdict
from
collections
import
namedtuple
,
defaultdict
from
ansible.executor.task_queue_manager
import
TaskQueueManager
from
ansible.executor.task_queue_manager
import
TaskQueueManager
...
@@ -249,12 +249,20 @@ class AdHocRunner(object):
...
@@ -249,12 +249,20 @@ class AdHocRunner(object):
self
.
loader
.
cleanup_all_tmp_files
()
self
.
loader
.
cleanup_all_tmp_files
()
def
clean_result
(
self
):
def
clean_result
(
self
):
result
=
defaultdict
(
dict
)
"""
for
host
,
msgs
in
self
.
results_callback
.
result_q
[
'contacted'
]
.
items
():
:return: {
result
[
host
][
'success'
]
=
len
(
msgs
)
"success": ['hostname',],
"failed": [{'hostname': 'msg'}, {}],
}
"""
result
=
{
'success'
:
[],
'failed'
:
[]}
for
host
in
self
.
results_callback
.
result_q
[
'contacted'
]:
result
[
'success'
]
.
append
(
host
)
for
host
,
msgs
in
self
.
results_callback
.
result_q
[
'dark'
]
.
items
():
for
host
,
msgs
in
self
.
results_callback
.
result_q
[
'dark'
]
.
items
():
result
[
host
][
'failed'
]
=
len
(
msgs
)
msg
=
'
\n
'
.
join
([
'{}: {}'
.
format
(
msg
.
get
(
'invocation'
,
{})
.
get
(
'module_name'
),
msg
.
get
(
'msg'
,
''
))
for
msg
in
msgs
])
result
[
'failed'
]
.
append
({
host
:
msg
})
return
result
return
result
...
...
This diff is collapsed.
Click to expand it.
apps/ops/views.py
View file @
a822f667
...
@@ -2,18 +2,15 @@
...
@@ -2,18 +2,15 @@
from
__future__
import
unicode_literals
from
__future__
import
unicode_literals
from
django.conf
import
settings
from
django.conf
import
settings
from
django.views.generic.list
import
ListView
,
MultipleObjectMixin
from
django.views.generic.list
import
ListView
from
django.views.generic.edit
import
CreateView
,
DeleteView
,
UpdateView
from
django.views.generic.detail
import
DetailView
,
SingleObjectMixin
from
users.utils
import
AdminUserRequiredMixin
from
users.utils
import
AdminUserRequiredMixin
from
ops.utils.mixins
import
CreateSudoPrivilegesMixin
,
ListSudoPrivilegesMixin
from
.models
import
TaskRecord
from
.models
import
Task
class
TaskListView
(
AdminUserRequiredMixin
,
ListView
):
class
TaskListView
(
AdminUserRequiredMixin
,
ListView
):
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
model
=
Task
model
=
Task
Record
context_object_name
=
'tasks'
context_object_name
=
'tasks'
template_name
=
'task/list.html'
template_name
=
'task/list.html'
...
@@ -25,18 +22,3 @@ class TaskListView(AdminUserRequiredMixin, ListView):
...
@@ -25,18 +22,3 @@ class TaskListView(AdminUserRequiredMixin, ListView):
kwargs
.
update
(
context
)
kwargs
.
update
(
context
)
return
super
(
TaskListView
,
self
)
.
get_context_data
(
**
kwargs
)
return
super
(
TaskListView
,
self
)
.
get_context_data
(
**
kwargs
)
class
TaskCreateView
(
AdminUserRequiredMixin
,
CreateView
):
model
=
Task
template_name
=
'task/create.html'
class
TaskUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
model
=
Task
template_name
=
'task/update.html'
class
TaskDetailView
(
DetailView
):
model
=
Task
context_object_name
=
'task'
template_name
=
'task/detail.html'
This diff is collapsed.
Click to expand it.
apps/perms/hands.py
View file @
a822f667
...
@@ -7,9 +7,4 @@ from assets.models import Asset, AssetGroup, SystemUser
...
@@ -7,9 +7,4 @@ from assets.models import Asset, AssetGroup, SystemUser
from
assets.serializers
import
AssetGrantedSerializer
,
AssetGroupSerializer
from
assets.serializers
import
AssetGrantedSerializer
,
AssetGroupSerializer
def
push_system_user
(
assets
,
system_user
):
print
(
'Push system user
%
s'
%
system_user
.
name
)
for
asset
in
assets
:
print
(
'
\t
Asset:
%
s'
%
asset
.
ip
)
This diff is collapsed.
Click to expand it.
apps/perms/templates/perms/asset_permission_create_update.html
View file @
a822f667
...
@@ -38,7 +38,7 @@
...
@@ -38,7 +38,7 @@
{{ form.user_groups|bootstrap_horizontal }}
{{ form.user_groups|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Asset' %}
</h3>
<h3>
{% trans 'Asset' %}
</h3>
{{ form.assets|bootstrap_horizontal }}
{{ form.assets|bootstrap_horizontal
|safe
}}
{{ form.asset_groups|bootstrap_horizontal }}
{{ form.asset_groups|bootstrap_horizontal }}
{{ form.system_users |bootstrap_horizontal }}
{{ form.system_users |bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
...
...
This diff is collapsed.
Click to expand it.
apps/perms/utils.py
View file @
a822f667
...
@@ -2,9 +2,11 @@
...
@@ -2,9 +2,11 @@
from
__future__
import
absolute_import
,
unicode_literals
from
__future__
import
absolute_import
,
unicode_literals
from
common.utils
import
setattr_bulk
from
common.utils
import
setattr_bulk
,
get_logger
from
.hands
import
User
,
UserGroup
,
Asset
,
AssetGroup
,
SystemUser
,
\
from
ops.tasks
import
push_users
push_system_user
from
.hands
import
User
,
UserGroup
,
Asset
,
AssetGroup
,
SystemUser
logger
=
get_logger
(
__file__
)
def
get_user_group_granted_asset_groups
(
user_group
):
def
get_user_group_granted_asset_groups
(
user_group
):
...
@@ -220,6 +222,19 @@ def get_users_granted_in_asset_group(asset):
...
@@ -220,6 +222,19 @@ def get_users_granted_in_asset_group(asset):
pass
pass
def
push_system_user
(
assets
,
system_user
):
logger
.
info
(
'Push system user
%
s'
%
system_user
.
name
)
for
asset
in
assets
:
logger
.
info
(
'
\t
Asset:
%
s'
%
asset
.
ip
)
if
not
assets
:
return
None
assets
=
[
asset
.
_to_secret_json
()
for
asset
in
assets
]
system_user
=
system_user
.
_to_secret_json
()
task
=
push_users
.
delay
(
assets
,
system_user
)
return
task
.
id
def
associate_system_users_and_assets
(
system_users
,
assets
,
asset_groups
):
def
associate_system_users_and_assets
(
system_users
,
assets
,
asset_groups
):
"""关联系统用户和资产, 目的是保存它们的关系, 然后新加入的资产或系统
"""关联系统用户和资产, 目的是保存它们的关系, 然后新加入的资产或系统
用户时,推送系统用户到资产
用户时,推送系统用户到资产
...
@@ -242,3 +257,5 @@ def associate_system_users_and_assets(system_users, assets, asset_groups):
...
@@ -242,3 +257,5 @@ def associate_system_users_and_assets(system_users, assets, asset_groups):
)
)
system_user
.
assets
.
add
(
*
(
tuple
(
assets_all
)))
system_user
.
assets
.
add
(
*
(
tuple
(
assets_all
)))
push_system_user
(
assets_need_push
,
system_user
)
push_system_user
(
assets_need_push
,
system_user
)
This diff is collapsed.
Click to expand it.
apps/perms/views.py
View file @
a822f667
# ~*~ coding: utf-8 ~*~
# ~*~ coding: utf-8 ~*~
from
__future__
import
unicode_literals
,
absolute_import
from
__future__
import
unicode_literals
,
absolute_import
import
functools
import
functools
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
django.db
import
transaction
from
django.conf
import
settings
from
django.conf
import
settings
from
django.db.models
import
Q
from
django.db.models
import
Q
from
django.views.generic
import
ListView
,
CreateView
,
UpdateView
from
django.views.generic
import
ListView
,
CreateView
,
UpdateView
...
@@ -65,6 +67,10 @@ class AssetPermissionCreateView(AdminUserRequiredMixin,
...
@@ -65,6 +67,10 @@ class AssetPermissionCreateView(AdminUserRequiredMixin,
template_name
=
'perms/asset_permission_create_update.html'
template_name
=
'perms/asset_permission_create_update.html'
success_url
=
reverse_lazy
(
'perms:asset-permission-list'
)
success_url
=
reverse_lazy
(
'perms:asset-permission-list'
)
@transaction.atomic
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
return
super
(
AssetPermissionCreateView
,
self
)
.
post
(
request
,
*
args
,
**
kwargs
)
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
context
=
{
'app'
:
_
(
'Perms'
),
'app'
:
_
(
'Perms'
),
...
...
This diff is collapsed.
Click to expand it.
requirements/requirements.txt
View file @
a822f667
...
@@ -19,3 +19,4 @@ itsdangerous==0.24
...
@@ -19,3 +19,4 @@ itsdangerous==0.24
tornado==4.4.2
tornado==4.4.2
eventlet==0.20.1
eventlet==0.20.1
django-filter==1.0.0
django-filter==1.0.0
passlib==1.7.1
This diff is collapsed.
Click to expand it.
run_server.py
View file @
a822f667
...
@@ -29,8 +29,9 @@ def start_django():
...
@@ -29,8 +29,9 @@ def start_django():
def
start_celery
():
def
start_celery
():
os
.
chdir
(
apps_dir
)
os
.
chdir
(
apps_dir
)
os
.
environ
.
setdefault
(
'C_FORCE_ROOT'
,
'1'
)
os
.
environ
.
setdefault
(
'C_FORCE_ROOT'
,
'1'
)
os
.
environ
.
setdefault
(
'PYTHONOPTIMIZE'
,
1
)
print
(
'start celery'
)
print
(
'start celery'
)
subprocess
.
call
(
'celery -A common worker -
P eventlet -s /tmp/celerybeat-schedule -l info
'
,
shell
=
True
)
subprocess
.
call
(
'celery -A common worker -
s /tmp/celerybeat-schedule -l debug
'
,
shell
=
True
)
def
main
():
def
main
():
...
...
This diff is collapsed.
Click to expand it.
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