mirror of
https://github.com/veops/cmdb.git
synced 2025-09-22 21:39:41 +08:00
Compare commits
529 Commits
dependabot
...
2.3.6
Author | SHA1 | Date | |
---|---|---|---|
|
dc1a2a7632 | ||
|
153fef4918 | ||
|
e218f8e065 | ||
|
b7137b3975 | ||
|
c6a9478dbb | ||
|
af40004fe9 | ||
|
d86eb1c5eb | ||
|
fef3bfceaf | ||
|
3a4f0b248f | ||
|
ffa3d7cd43 | ||
|
6aefac98cd | ||
|
22989f8d5a | ||
|
ebe9d1e29f | ||
|
f1dd5ca074 | ||
|
4dd95f0d7e | ||
|
7e3e248c2b | ||
|
a5ff1139f7 | ||
|
00135f4644 | ||
|
8297d4c9b4 | ||
|
5143539593 | ||
|
a6eb2f0d21 | ||
|
07a63bef6e | ||
|
d69efeea25 | ||
|
0ef67360ad | ||
|
e2f993bc11 | ||
|
05d2795e79 | ||
|
6ff77a140c | ||
|
6503d32e6e | ||
|
887a69c2bd | ||
|
6d052eaffc | ||
|
d0f0bf84dd | ||
|
802fda66e7 | ||
|
c95747c88a | ||
|
ed49b238d8 | ||
|
375f0879fb | ||
|
8bc1893ca9 | ||
|
53cd2342bf | ||
|
eff6d974d4 | ||
|
8478d2f858 | ||
|
80e99cc335 | ||
|
8f64fc4aa0 | ||
|
cfc345c993 | ||
|
928116d0b5 | ||
|
4c2e6ae69f | ||
|
a2c75fd34e | ||
|
8217053abf | ||
|
8c17373e45 | ||
|
a8e2595327 | ||
|
dfbba103cd | ||
|
86b9d5a7f4 | ||
|
612922a1b7 | ||
|
2758c5e468 | ||
|
d85c86a839 | ||
|
8355137e43 | ||
|
2e644233bc | ||
|
d9b4082b46 | ||
|
a07f984152 | ||
|
4cab7ef6b0 | ||
|
070c163de6 | ||
|
282a779fb1 | ||
|
cb6b51a84c | ||
|
34bd320e75 | ||
|
1eca5791f6 | ||
|
13b1c9a30c | ||
|
b1a15a85d2 | ||
|
08e5a02caf | ||
|
308827b8fc | ||
|
dc4ccb22b9 | ||
|
c482e7ea43 | ||
|
663c14f763 | ||
|
c6ee227bab | ||
|
cb62cf2410 | ||
|
133f32a6b0 | ||
|
45c48c86fe | ||
|
2321f17dae | ||
|
ddb31a07a2 | ||
|
b474914fbb | ||
|
26099a3d69 | ||
|
62829c885b | ||
|
260aed6462 | ||
|
3841999cca | ||
|
14c03ce5d2 | ||
|
f463ecd6e6 | ||
|
adc0cfd5c5 | ||
|
086481657e | ||
|
d2f84ae3dc | ||
|
9f1b510cb3 | ||
|
61acb2483d | ||
|
0196c8a82c | ||
|
bed2323fc1 | ||
|
be9b308f56 | ||
|
8ba658ea1b | ||
|
0aa668cfa0 | ||
|
e20fd33a53 | ||
|
7462de63de | ||
|
5f9ba069ad | ||
|
5dc0d95ff8 | ||
|
e5536b76e6 | ||
|
8b044efd4e | ||
|
747b5bf494 | ||
|
21067022f6 | ||
|
4102c44fb2 | ||
|
600f95ce18 | ||
|
950fd38044 | ||
|
01085615b5 | ||
|
734f1940f9 | ||
|
c25c1e4e4b | ||
|
826a8306d3 | ||
|
740aae573e | ||
|
17828a7631 | ||
|
02cb497bdc | ||
|
05a7dc41ee | ||
|
459c70ba2d | ||
|
774f42ac34 | ||
|
420029a5e2 | ||
|
ab8acbfd20 | ||
|
4468b6a8de | ||
|
6bf145d085 | ||
|
42b1e47e76 | ||
|
673134003a | ||
|
ef67885571 | ||
|
075bf7217f | ||
|
3b7b8f435c | ||
|
2b7f6aeef3 | ||
|
544fac8aca | ||
|
3d0a56ec8c | ||
|
d2d8482052 | ||
|
a0afae8d2e | ||
|
9f3da68636 | ||
|
24b955c288 | ||
|
a07b2d37ec | ||
|
c86fcb4e7b | ||
|
ca7964f24b | ||
|
c42ac634fb | ||
|
a6fc3341ce | ||
|
fc3f2e25f3 | ||
|
511a5f70c6 | ||
|
f8ff4d5e45 | ||
|
3ab72cceaf | ||
|
4ab7e3c70c | ||
|
a7fe75f7df | ||
|
3474a71a75 | ||
|
6531baff64 | ||
|
ed5936250f | ||
|
52c32e2ab1 | ||
|
d3224625b6 | ||
|
f158c7e33a | ||
|
6dc12bb6ac | ||
|
b33ae16c00 | ||
|
2caffc2670 | ||
|
f28af51007 | ||
|
3a0369559f | ||
|
a74a2c5a94 | ||
|
9fbcb2838e | ||
|
60a445b972 | ||
|
bfdd7b6a0e | ||
|
ab093d2493 | ||
|
315a578a31 | ||
|
1e16dc5e5b | ||
|
f67e196acf | ||
|
439e25d5dd | ||
|
ea59c0d71f | ||
|
1137127aab | ||
|
4ad1b5282e | ||
|
cdd5e4d9aa | ||
|
432de5e847 | ||
|
3a2339765a | ||
|
b5a2af7420 | ||
|
8b267613d6 | ||
|
b365eb27f6 | ||
|
2125f020b5 | ||
|
ea762e35a0 | ||
|
f11aadf6d4 | ||
|
9cbf133b9f | ||
|
95e8f9de74 | ||
|
26792147ae | ||
|
4f9b581c2e | ||
|
e2b1cb3003 | ||
|
f75a85b48a | ||
|
313fc80e54 | ||
|
e0666689e5 | ||
|
7a9fd4f9d6 | ||
|
2fd706be85 | ||
|
3df51bb670 | ||
|
9bbbcbe6dc | ||
|
16d6b40e8d | ||
|
ef2d3812a2 | ||
|
bc653efd04 | ||
|
d891d7365d | ||
|
9953b2fc98 | ||
|
8de54812dc | ||
|
eb7d52cf35 | ||
|
6c4a5f2f6b | ||
|
17c5d4538b | ||
|
6c3e3f9eed | ||
|
b0494adc17 | ||
|
fc133f2ae9 | ||
|
ac6e3a0318 | ||
|
404ec976cc | ||
|
4211bbcbc9 | ||
|
0158636671 | ||
|
d986bc3bbc | ||
|
044b820548 | ||
|
536daa6d4f | ||
|
b0620b043b | ||
|
a88c9cf7f7 | ||
|
be50f505d1 | ||
|
0bb4f633d6 | ||
|
78b521f3af | ||
|
77bc850d4a | ||
|
e52f201ba1 | ||
|
64aea424dc | ||
|
0655b0e9eb | ||
|
cce0649299 | ||
|
52574c64cc | ||
|
fb904b01a6 | ||
|
63af79ec45 | ||
|
38af86317a | ||
|
03bac86588 | ||
|
130b68cadd | ||
|
65000f8141 | ||
|
23692ad50b | ||
|
16cd34e8b8 | ||
|
985f67ee47 | ||
|
8d95f8d57d | ||
|
cf6230008d | ||
|
ec97fa84d8 | ||
|
76f074704b | ||
|
e5addab3af | ||
|
1c6be9e281 | ||
|
9552892c68 | ||
|
b59e1af318 | ||
|
d164d883ab | ||
|
1fef160d9e | ||
|
2e537d390a | ||
|
5b9fe15afa | ||
|
89fa5f2243 | ||
|
652a5c7fb8 | ||
|
afb6adec89 | ||
|
a9db4285ab | ||
|
a04bdc29a5 | ||
|
91e0e076a7 | ||
|
339a7b857e | ||
|
e86e5ad1fd | ||
|
c50a69de77 | ||
|
4d16e9e6d9 | ||
|
fcea4dcb9f | ||
|
f98fd24c62 | ||
|
f10eeb8439 | ||
|
f070948122 | ||
|
4112bcf547 | ||
|
2292756bf7 | ||
|
93e2483974 | ||
|
fbb4fcc255 | ||
|
fc77241006 | ||
|
0d04ad7d90 | ||
|
e6290e49ea | ||
|
97aa2e0ebe | ||
|
939d9dc3cd | ||
|
576d2e3bc4 | ||
|
9a40246d29 | ||
|
044f95c3be | ||
|
a386de355e | ||
|
b93afc1790 | ||
|
77d89677ef | ||
|
7ec6775f03 | ||
|
98cc853dbc | ||
|
f57ff80099 | ||
|
51e4b5dd8f | ||
|
dbf44a020b | ||
|
8e578797ef | ||
|
158de4b946 | ||
|
3cf234d49e | ||
|
a7debc1b3b | ||
|
9268da2ffa | ||
|
cfcb092478 | ||
|
0d8b41b64a | ||
|
d85715793f | ||
|
afbdbe4682 | ||
|
e629abebb7 | ||
|
029c12365a | ||
|
4d000d9805 | ||
|
f1fc66bd2c | ||
|
d6af4af1d1 | ||
|
7fe2bdca5f | ||
|
1432131d2b | ||
|
bc94d039f5 | ||
|
5abafed9c8 | ||
|
04e249feac | ||
|
ef3e6bc6b0 | ||
|
d9d5f8f818 | ||
|
578da0807c | ||
|
3eb35f5497 | ||
|
9669ad04cd | ||
|
70214807ca | ||
|
7c1c309f7a | ||
|
9b9799ff5e | ||
|
b2578b61fa | ||
|
619f47ae13 | ||
|
37c5e31799 | ||
|
ab70b2a655 | ||
|
c285606f4a | ||
|
6d3611bd73 | ||
|
764f6a07e0 | ||
|
ae8d487af4 | ||
|
87c6554555 | ||
|
f5671c2a2a | ||
|
43ad3dfa7b | ||
|
29fa17a0b8 | ||
|
5191d6ed73 | ||
|
8348f8e7b1 | ||
|
75c48a0807 | ||
|
5b38385f7e | ||
|
036e1d236b | ||
|
c31be0f753 | ||
|
764d2fac3f | ||
|
f4079e9c3e | ||
|
2a0ed72235 | ||
|
9e803ae4c7 | ||
|
bebdb61adf | ||
|
f49cad771b | ||
|
a5b4fbda40 | ||
|
2cce2d5cf2 | ||
|
e720b7af66 | ||
|
09e4a5111b | ||
|
3539b12503 | ||
|
21d8673b5d | ||
|
7154426dc7 | ||
|
ca75c7dcd0 | ||
|
194a2254a6 | ||
|
26abad14d0 | ||
|
1521a71f9c | ||
|
d425b455f1 | ||
|
230307474b | ||
|
69d6b40e39 | ||
|
5dc2f89e7f | ||
|
9eaca4d6a0 | ||
|
3680a462f5 | ||
|
3ac50e7cd8 | ||
|
21b2cc1d5d | ||
|
cd5448cc7d | ||
|
10610bdb4b | ||
|
b5c2156387 | ||
|
b05ae0d1a7 | ||
|
bbf6138d43 | ||
|
1ba3e6a680 | ||
|
64045c1f93 | ||
|
5a3e55813c | ||
|
bc72e58886 | ||
|
9e78955ba1 | ||
|
136853d9a4 | ||
|
036e3ad00d | ||
|
5ce6c93237 | ||
|
43dba7f7ed | ||
|
f4879d20d6 | ||
|
740e4c6034 | ||
|
0f2baa1d94 | ||
|
405b0af72c | ||
|
a4e5178979 | ||
|
c14fe23283 | ||
|
b3a058f908 | ||
|
bd82a0e27c | ||
|
f22a5c3543 | ||
|
ed81c3f091 | ||
|
07814b85f9 | ||
|
db52b28d6b | ||
|
fc85ba21c8 | ||
|
6c5ee3fcd9 | ||
|
40f1ef88a9 | ||
|
bce422ffc8 | ||
|
7c79066532 | ||
|
1129ac93fb | ||
|
5ab0e7e737 | ||
|
23319c7417 | ||
|
c74f85cabb | ||
|
fce2b689fb | ||
|
105327bb0c | ||
|
745c43d0a4 | ||
|
3130d94568 | ||
|
04a66eb239 | ||
|
68390ec6f1 | ||
|
17392be138 | ||
|
f2fdb29221 | ||
|
4a18698423 | ||
|
95ccee04f9 | ||
|
b60628247b | ||
|
a6d7699ab4 | ||
|
4b21bcc438 | ||
|
33dce2f0f3 | ||
|
d43b827fe5 | ||
|
aec8bade41 | ||
|
89ae89a449 | ||
|
945f90e386 | ||
|
2ba6a16613 | ||
|
6089039366 | ||
|
e1e5307084 | ||
|
2ff7fce9dd | ||
|
fc4d3e0c1a | ||
|
f66a94712e | ||
|
24664c7686 | ||
|
1d668bab6e | ||
|
3d4b84909e | ||
|
8341e742eb | ||
|
a71ba83de0 | ||
|
9668131c18 | ||
|
4a744dcad9 | ||
|
2a420225e2 | ||
|
ff67785618 | ||
|
dfe1ba55d5 | ||
|
90b1b6b7af | ||
|
d5fbe42ed7 | ||
|
f424ad6864 | ||
|
16b724bd40 | ||
|
f70ed54cad | ||
|
dd64564160 | ||
|
cc2cdbcc9f | ||
|
81fe850627 | ||
|
487d9f76f6 | ||
|
92dd4c5dfe | ||
|
8ee7c6daf8 | ||
|
882b158d18 | ||
|
85222443c0 | ||
|
1696ecf49d | ||
|
73b92ff533 | ||
|
e977bb15a5 | ||
|
7c46d6cdbf | ||
|
4d11c1f7db | ||
|
0a563deb11 | ||
|
ba80ec4403 | ||
|
3b7cc4595b | ||
|
9fe47657a6 | ||
|
5a4a6caa07 | ||
|
9dadbe1599 | ||
|
40d016f513 | ||
|
655edaa7c8 | ||
|
7fa5cff919 | ||
|
d19834ed5d | ||
|
b6be430aa3 | ||
|
63792c242f | ||
|
10f7029722 | ||
|
ba176542dc | ||
|
aae3b6e2ff | ||
|
b370c7d46e | ||
|
efa5a8ea5d | ||
|
fd532626ac | ||
|
617337c614 | ||
|
9a3d24ac81 | ||
|
454dd4c56b | ||
|
88ad72d4dc | ||
|
8d1517d550 | ||
|
d3a8ef5966 | ||
|
e5baa5012d | ||
|
a1f63b00dd | ||
|
47ded84231 | ||
|
224a48a5f3 | ||
|
0e7c52df71 | ||
|
ff701cc770 | ||
|
6a7bb725cc | ||
|
0a13186c13 | ||
|
a0ffeb9950 | ||
|
6c70ec6d53 | ||
|
4b5f82699a | ||
|
f78c3b928b | ||
|
332659c1d5 | ||
|
3beb2706dc | ||
|
a14111e1ce | ||
|
c4320c14f9 | ||
|
4c5442748f | ||
|
a81750acba | ||
|
0439e2462b | ||
|
3b62bd7ac9 | ||
|
f6add52721 | ||
|
c85e535288 | ||
|
c0c6d116b5 | ||
|
39153e92d1 | ||
|
42bcc2e510 | ||
|
398fbb25dc | ||
|
4b312d4f99 | ||
|
10414155a5 | ||
|
feda0c37e7 | ||
|
173c120b64 | ||
|
5f2a0d1a7b | ||
|
50f894a01d | ||
|
66e93e73af | ||
|
58ad9d3f05 | ||
|
08c96039e9 | ||
|
ca0dd97626 | ||
|
7810ee3974 | ||
|
2cfea7ef08 | ||
|
0cee6cea25 | ||
|
5d13ba2f26 | ||
|
a583433530 | ||
|
733ac3b2b4 | ||
|
ef6300255a | ||
|
aad37dcf0b | ||
|
cce10d39ea | ||
|
c521dd447e | ||
|
4d0cd4ba56 | ||
|
7291274cb1 | ||
|
44f2e383c3 | ||
|
1f8219b418 | ||
|
cb2f170ded | ||
|
1241a23ba8 | ||
|
7d7744b7dc | ||
|
9c7d51127a | ||
|
b5a987f6b4 | ||
|
7bbc68bfd5 | ||
|
99d11e11ce | ||
|
7b96ac4638 | ||
|
0a36330852 | ||
|
9105f92c82 | ||
|
57541ab486 | ||
|
a0fcbd220e | ||
|
d54b404eb6 | ||
|
620c5bb5eb | ||
|
0fde1d699d | ||
|
61f77cf311 | ||
|
13476128d5 | ||
|
5cdb4ecd2a | ||
|
64c3b9da3b | ||
|
55dad7a58c | ||
|
38dabc35e5 | ||
|
5b4f95a50e | ||
|
f3046d3c91 | ||
|
5faae9af67 | ||
|
c0b50642e0 | ||
|
12ca296879 | ||
|
420c6cea2b | ||
|
ccc4bb48fa |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -70,7 +70,6 @@ settings.py
|
|||||||
# UI
|
# UI
|
||||||
cmdb-ui/node_modules
|
cmdb-ui/node_modules
|
||||||
cmdb-ui/dist
|
cmdb-ui/dist
|
||||||
cmdb-ui/yarn.lock
|
|
||||||
|
|
||||||
# Log files
|
# Log files
|
||||||
cmdb-ui/npm-debug.log*
|
cmdb-ui/npm-debug.log*
|
||||||
|
@@ -6,7 +6,7 @@ name = "pypi"
|
|||||||
[packages]
|
[packages]
|
||||||
# Flask
|
# Flask
|
||||||
Flask = "==2.3.2"
|
Flask = "==2.3.2"
|
||||||
Werkzeug = ">=2.3.6"
|
Werkzeug = "==2.3.6"
|
||||||
click = ">=5.0"
|
click = ">=5.0"
|
||||||
# Api
|
# Api
|
||||||
Flask-RESTful = "==0.3.10"
|
Flask-RESTful = "==0.3.10"
|
||||||
@@ -21,7 +21,7 @@ Flask-Migrate = "==2.5.2"
|
|||||||
gunicorn = "==21.0.1"
|
gunicorn = "==21.0.1"
|
||||||
supervisor = "==4.0.3"
|
supervisor = "==4.0.3"
|
||||||
# Auth
|
# Auth
|
||||||
Flask-Login = ">=0.6.2"
|
Flask-Login = "==0.6.2"
|
||||||
Flask-Bcrypt = "==1.0.1"
|
Flask-Bcrypt = "==1.0.1"
|
||||||
Flask-Cors = ">=3.0.8"
|
Flask-Cors = ">=3.0.8"
|
||||||
ldap3 = "==2.9.1"
|
ldap3 = "==2.9.1"
|
||||||
@@ -43,7 +43,7 @@ WTForms = "==3.0.0"
|
|||||||
email-validator = "==1.3.1"
|
email-validator = "==1.3.1"
|
||||||
treelib = "==1.6.1"
|
treelib = "==1.6.1"
|
||||||
flasgger = "==0.9.5"
|
flasgger = "==0.9.5"
|
||||||
Pillow = ">=10.0.1"
|
Pillow = "==9.3.0"
|
||||||
# other
|
# other
|
||||||
six = "==1.16.0"
|
six = "==1.16.0"
|
||||||
bs4 = ">=0.0.1"
|
bs4 = ">=0.0.1"
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
import click
|
import click
|
||||||
from flask.cli import with_appcontext
|
from flask.cli import with_appcontext
|
||||||
|
|
||||||
from api.lib.perm.acl.user import UserCRUD
|
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
@with_appcontext
|
@with_appcontext
|
||||||
@@ -25,18 +23,50 @@ def init_acl():
|
|||||||
role_rebuild.apply_async(args=(role.id, app.id), queue=ACL_QUEUE)
|
role_rebuild.apply_async(args=(role.id, app.id), queue=ACL_QUEUE)
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
# @click.command()
|
||||||
@with_appcontext
|
# @with_appcontext
|
||||||
def add_user():
|
# def acl_clean():
|
||||||
"""
|
# from api.models.acl import Resource
|
||||||
create a user
|
# from api.models.acl import Permission
|
||||||
|
# from api.models.acl import RolePermission
|
||||||
is_admin: default is False
|
#
|
||||||
|
# perms = RolePermission.get_by(to_dict=False)
|
||||||
"""
|
#
|
||||||
|
# for r in perms:
|
||||||
username = click.prompt('Enter username', confirmation_prompt=False)
|
# perm = Permission.get_by_id(r.perm_id)
|
||||||
password = click.prompt('Enter password', hide_input=True, confirmation_prompt=True)
|
# if perm and perm.app_id != r.app_id:
|
||||||
email = click.prompt('Enter email ', confirmation_prompt=False)
|
# resource_id = r.resource_id
|
||||||
|
# resource = Resource.get_by_id(resource_id)
|
||||||
UserCRUD.add(username=username, password=password, email=email)
|
# perm_name = perm.name
|
||||||
|
# existed = Permission.get_by(resource_type_id=resource.resource_type_id, name=perm_name, first=True,
|
||||||
|
# to_dict=False)
|
||||||
|
# if existed is not None:
|
||||||
|
# other = RolePermission.get_by(rid=r.rid, perm_id=existed.id, resource_id=resource_id)
|
||||||
|
# if not other:
|
||||||
|
# r.update(perm_id=existed.id)
|
||||||
|
# else:
|
||||||
|
# r.soft_delete()
|
||||||
|
# else:
|
||||||
|
# r.soft_delete()
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# @click.command()
|
||||||
|
# @with_appcontext
|
||||||
|
# def acl_has_resource_role():
|
||||||
|
# from api.models.acl import Role
|
||||||
|
# from api.models.acl import App
|
||||||
|
# from api.lib.perm.acl.cache import HasResourceRoleCache
|
||||||
|
# from api.lib.perm.acl.role import RoleCRUD
|
||||||
|
#
|
||||||
|
# roles = Role.get_by(to_dict=False)
|
||||||
|
# apps = App.get_by(to_dict=False)
|
||||||
|
# for role in roles:
|
||||||
|
# if role.app_id:
|
||||||
|
# res = RoleCRUD.recursive_resources(role.id, role.app_id)
|
||||||
|
# if res.get('resources') or res.get('groups'):
|
||||||
|
# HasResourceRoleCache.add(role.id, role.app_id)
|
||||||
|
# else:
|
||||||
|
# for app in apps:
|
||||||
|
# res = RoleCRUD.recursive_resources(role.id, app.id)
|
||||||
|
# if res.get('resources') or res.get('groups'):
|
||||||
|
# HasResourceRoleCache.add(role.id, app.id)
|
||||||
|
@@ -29,6 +29,7 @@ from api.lib.perm.acl.cache import AppCache
|
|||||||
from api.lib.perm.acl.resource import ResourceCRUD
|
from api.lib.perm.acl.resource import ResourceCRUD
|
||||||
from api.lib.perm.acl.resource import ResourceTypeCRUD
|
from api.lib.perm.acl.resource import ResourceTypeCRUD
|
||||||
from api.lib.perm.acl.role import RoleCRUD
|
from api.lib.perm.acl.role import RoleCRUD
|
||||||
|
from api.lib.perm.acl.user import UserCRUD
|
||||||
from api.lib.secrets.inner import KeyManage
|
from api.lib.secrets.inner import KeyManage
|
||||||
from api.lib.secrets.inner import global_key_threshold
|
from api.lib.secrets.inner import global_key_threshold
|
||||||
from api.lib.secrets.secrets import InnerKVManger
|
from api.lib.secrets.secrets import InnerKVManger
|
||||||
@@ -127,10 +128,10 @@ def cmdb_init_acl():
|
|||||||
|
|
||||||
# 3. add resource and grant
|
# 3. add resource and grant
|
||||||
ci_types = CIType.get_by(to_dict=False)
|
ci_types = CIType.get_by(to_dict=False)
|
||||||
resource_type_id = ResourceType.get_by(name=ResourceTypeEnum.CI, first=True, to_dict=False).id
|
type_id = ResourceType.get_by(name=ResourceTypeEnum.CI, first=True, to_dict=False).id
|
||||||
for ci_type in ci_types:
|
for ci_type in ci_types:
|
||||||
try:
|
try:
|
||||||
ResourceCRUD.add(ci_type.name, resource_type_id, app_id)
|
ResourceCRUD.add(ci_type.name, type_id, app_id)
|
||||||
except AbortException:
|
except AbortException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -140,10 +141,10 @@ def cmdb_init_acl():
|
|||||||
[PermEnum.READ])
|
[PermEnum.READ])
|
||||||
|
|
||||||
relation_views = PreferenceRelationView.get_by(to_dict=False)
|
relation_views = PreferenceRelationView.get_by(to_dict=False)
|
||||||
resource_type_id = ResourceType.get_by(name=ResourceTypeEnum.RELATION_VIEW, first=True, to_dict=False).id
|
type_id = ResourceType.get_by(name=ResourceTypeEnum.RELATION_VIEW, first=True, to_dict=False).id
|
||||||
for view in relation_views:
|
for view in relation_views:
|
||||||
try:
|
try:
|
||||||
ResourceCRUD.add(view.name, resource_type_id, app_id)
|
ResourceCRUD.add(view.name, type_id, app_id)
|
||||||
except AbortException:
|
except AbortException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -153,6 +154,57 @@ def cmdb_init_acl():
|
|||||||
[PermEnum.READ])
|
[PermEnum.READ])
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
@click.option(
|
||||||
|
'-u',
|
||||||
|
'--user',
|
||||||
|
help='username'
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
'-p',
|
||||||
|
'--password',
|
||||||
|
help='password'
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
'-m',
|
||||||
|
'--mail',
|
||||||
|
help='mail'
|
||||||
|
)
|
||||||
|
@with_appcontext
|
||||||
|
def add_user(user, password, mail):
|
||||||
|
"""
|
||||||
|
create a user
|
||||||
|
|
||||||
|
is_admin: default is False
|
||||||
|
|
||||||
|
Example: flask add-user -u <username> -p <password> -m <mail>
|
||||||
|
"""
|
||||||
|
assert user is not None
|
||||||
|
assert password is not None
|
||||||
|
assert mail is not None
|
||||||
|
UserCRUD.add(username=user, password=password, email=mail)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
@click.option(
|
||||||
|
'-u',
|
||||||
|
'--user',
|
||||||
|
help='username'
|
||||||
|
)
|
||||||
|
@with_appcontext
|
||||||
|
def del_user(user):
|
||||||
|
"""
|
||||||
|
delete a user
|
||||||
|
|
||||||
|
Example: flask del-user -u <username>
|
||||||
|
"""
|
||||||
|
assert user is not None
|
||||||
|
from api.models.acl import User
|
||||||
|
|
||||||
|
u = User.get_by(username=user, first=True, to_dict=False)
|
||||||
|
u and UserCRUD.delete(u.uid)
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
@with_appcontext
|
@with_appcontext
|
||||||
def cmdb_counter():
|
def cmdb_counter():
|
||||||
@@ -277,6 +329,7 @@ def valid_address(address):
|
|||||||
}
|
}
|
||||||
KeyManage.print_response(response)
|
KeyManage.print_response(response)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@@ -391,7 +444,6 @@ def cmdb_password_data_migrate():
|
|||||||
|
|
||||||
value_table = CIIndexValueText if attr.is_index else CIValueText
|
value_table = CIIndexValueText if attr.is_index else CIValueText
|
||||||
|
|
||||||
failed = False
|
|
||||||
for i in value_table.get_by(attr_id=attr.id, to_dict=False):
|
for i in value_table.get_by(attr_id=attr.id, to_dict=False):
|
||||||
if current_app.config.get("SECRETS_ENGINE", 'inner') == 'inner':
|
if current_app.config.get("SECRETS_ENGINE", 'inner') == 'inner':
|
||||||
_, status = InnerCrypt().decrypt(i.value)
|
_, status = InnerCrypt().decrypt(i.value)
|
||||||
@@ -402,7 +454,6 @@ def cmdb_password_data_migrate():
|
|||||||
if status:
|
if status:
|
||||||
CIValueText.create(ci_id=i.ci_id, attr_id=attr.id, value=encrypt_value)
|
CIValueText.create(ci_id=i.ci_id, attr_id=attr.id, value=encrypt_value)
|
||||||
else:
|
else:
|
||||||
failed = True
|
|
||||||
continue
|
continue
|
||||||
elif current_app.config.get("SECRETS_ENGINE") == 'vault':
|
elif current_app.config.get("SECRETS_ENGINE") == 'vault':
|
||||||
if i.value == '******':
|
if i.value == '******':
|
||||||
@@ -413,48 +464,8 @@ def cmdb_password_data_migrate():
|
|||||||
vault.update("/{}/{}".format(i.ci_id, i.attr_id), dict(v=i.value))
|
vault.update("/{}/{}".format(i.ci_id, i.attr_id), dict(v=i.value))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print('save password to vault failed: {}'.format(e))
|
print('save password to vault failed: {}'.format(e))
|
||||||
failed = True
|
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
i.delete()
|
i.delete()
|
||||||
|
|
||||||
if not failed and attr.is_index:
|
|
||||||
attr.update(is_index=False)
|
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
|
||||||
@with_appcontext
|
|
||||||
def cmdb_agent_init():
|
|
||||||
"""
|
|
||||||
Initialize the agent's permissions and obtain the key and secret
|
|
||||||
"""
|
|
||||||
|
|
||||||
from api.models.acl import User
|
|
||||||
|
|
||||||
user = User.get_by(username="cmdb_agent", first=True, to_dict=False)
|
|
||||||
if user is None:
|
|
||||||
click.echo(
|
|
||||||
click.style('user cmdb_agent does not exist, please use flask add-user to create it first', fg='red'))
|
|
||||||
return
|
|
||||||
|
|
||||||
# grant
|
|
||||||
_app = AppCache.get('cmdb') or App.create(name='cmdb')
|
|
||||||
app_id = _app.id
|
|
||||||
|
|
||||||
ci_types = CIType.get_by(to_dict=False)
|
|
||||||
resource_type_id = ResourceType.get_by(name=ResourceTypeEnum.CI, first=True, to_dict=False).id
|
|
||||||
for ci_type in ci_types:
|
|
||||||
try:
|
|
||||||
ResourceCRUD.add(ci_type.name, resource_type_id, app_id)
|
|
||||||
except AbortException:
|
|
||||||
pass
|
|
||||||
|
|
||||||
ACLManager().grant_resource_to_role(ci_type.name,
|
|
||||||
"cmdb_agent",
|
|
||||||
ResourceTypeEnum.CI,
|
|
||||||
[PermEnum.READ, PermEnum.UPDATE, PermEnum.ADD, PermEnum.DELETE])
|
|
||||||
|
|
||||||
click.echo("Key : {}".format(click.style(user.key, bg='red')))
|
|
||||||
click.echo("Secret: {}".format(click.style(user.secret, bg='red')))
|
|
||||||
|
@@ -10,6 +10,9 @@ from api.models.common_setting import Employee, Department
|
|||||||
|
|
||||||
|
|
||||||
class InitEmployee(object):
|
class InitEmployee(object):
|
||||||
|
"""
|
||||||
|
初始化员工
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.log = current_app.logger
|
self.log = current_app.logger
|
||||||
@@ -55,8 +58,7 @@ class InitEmployee(object):
|
|||||||
self.log.error(ErrFormat.acl_import_user_failed.format(user['username'], str(e)))
|
self.log.error(ErrFormat.acl_import_user_failed.format(user['username'], str(e)))
|
||||||
self.log.error(e)
|
self.log.error(e)
|
||||||
|
|
||||||
@staticmethod
|
def get_rid_by_uid(self, uid):
|
||||||
def get_rid_by_uid(uid):
|
|
||||||
from api.models.acl import Role
|
from api.models.acl import Role
|
||||||
role = Role.get_by(first=True, uid=uid)
|
role = Role.get_by(first=True, uid=uid)
|
||||||
return role['id'] if role is not None else 0
|
return role['id'] if role is not None else 0
|
||||||
@@ -69,8 +71,7 @@ class InitDepartment(object):
|
|||||||
def init(self):
|
def init(self):
|
||||||
self.init_wide_company()
|
self.init_wide_company()
|
||||||
|
|
||||||
@staticmethod
|
def hard_delete(self, department_id, department_name):
|
||||||
def hard_delete(department_id, department_name):
|
|
||||||
existed_deleted_list = Department.query.filter(
|
existed_deleted_list = Department.query.filter(
|
||||||
Department.department_name == department_name,
|
Department.department_name == department_name,
|
||||||
Department.department_id == department_id,
|
Department.department_id == department_id,
|
||||||
@@ -79,12 +80,11 @@ class InitDepartment(object):
|
|||||||
for existed in existed_deleted_list:
|
for existed in existed_deleted_list:
|
||||||
existed.delete()
|
existed.delete()
|
||||||
|
|
||||||
@staticmethod
|
def get_department(self, department_name):
|
||||||
def get_department(department_name):
|
|
||||||
return Department.query.filter(
|
return Department.query.filter(
|
||||||
Department.department_name == department_name,
|
Department.department_name == department_name,
|
||||||
Department.deleted == 0,
|
Department.deleted == 0,
|
||||||
).first()
|
).order_by(Department.created_at.asc()).first()
|
||||||
|
|
||||||
def run(self, department_id, department_name, department_parent_id):
|
def run(self, department_id, department_name, department_parent_id):
|
||||||
self.hard_delete(department_id, department_name)
|
self.hard_delete(department_id, department_name)
|
||||||
@@ -94,7 +94,7 @@ class InitDepartment(object):
|
|||||||
if res.department_id == department_id:
|
if res.department_id == department_id:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
res.update(
|
new_d = res.update(
|
||||||
department_id=department_id,
|
department_id=department_id,
|
||||||
department_parent_id=department_parent_id,
|
department_parent_id=department_parent_id,
|
||||||
)
|
)
|
||||||
@@ -108,11 +108,11 @@ class InitDepartment(object):
|
|||||||
new_d = self.get_department(department_name)
|
new_d = self.get_department(department_name)
|
||||||
|
|
||||||
if new_d.department_id != department_id:
|
if new_d.department_id != department_id:
|
||||||
new_d.update(
|
new_d = new_d.update(
|
||||||
department_id=department_id,
|
department_id=department_id,
|
||||||
department_parent_id=department_parent_id,
|
department_parent_id=department_parent_id,
|
||||||
)
|
)
|
||||||
self.log.info(f"init {department_name} success.")
|
self.log.info(f"初始化 {department_name} 部门成功.")
|
||||||
|
|
||||||
def run_common(self, department_id, department_name, department_parent_id):
|
def run_common(self, department_id, department_name, department_parent_id):
|
||||||
try:
|
try:
|
||||||
@@ -123,14 +123,19 @@ class InitDepartment(object):
|
|||||||
raise Exception(e)
|
raise Exception(e)
|
||||||
|
|
||||||
def init_wide_company(self):
|
def init_wide_company(self):
|
||||||
|
"""
|
||||||
|
创建 id 0, name 全公司 的部门
|
||||||
|
"""
|
||||||
department_id = 0
|
department_id = 0
|
||||||
department_name = '全公司'
|
department_name = '全公司'
|
||||||
department_parent_id = -1
|
department_parent_id = -1
|
||||||
|
|
||||||
self.run_common(department_id, department_name, department_parent_id)
|
self.run_common(department_id, department_name, department_parent_id)
|
||||||
|
|
||||||
@staticmethod
|
def create_acl_role_with_department(self):
|
||||||
def create_acl_role_with_department():
|
"""
|
||||||
|
当前所有部门,在ACL创建 role
|
||||||
|
"""
|
||||||
acl = ACLManager('acl')
|
acl = ACLManager('acl')
|
||||||
role_name_map = {role['name']: role for role in acl.get_all_roles()}
|
role_name_map = {role['name']: role for role in acl.get_all_roles()}
|
||||||
|
|
||||||
@@ -141,7 +146,7 @@ class InitDepartment(object):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
role = role_name_map.get(department.department_name)
|
role = role_name_map.get(department.department_name)
|
||||||
if not role:
|
if role is None:
|
||||||
payload = {
|
payload = {
|
||||||
'app_id': 'acl',
|
'app_id': 'acl',
|
||||||
'name': department.department_name,
|
'name': department.department_name,
|
||||||
@@ -203,20 +208,25 @@ class InitDepartment(object):
|
|||||||
if acl_rid > 0:
|
if acl_rid > 0:
|
||||||
acl.grant_resource(acl_rid, resource['id'], perms)
|
acl.grant_resource(acl_rid, resource['id'], perms)
|
||||||
|
|
||||||
@staticmethod
|
def check_app(self, app_name):
|
||||||
def check_app(app_name):
|
|
||||||
acl = ACLManager(app_name)
|
acl = ACLManager(app_name)
|
||||||
payload = dict(
|
payload = dict(
|
||||||
name=app_name,
|
name=app_name,
|
||||||
description=app_name
|
description=app_name
|
||||||
)
|
)
|
||||||
|
try:
|
||||||
app = acl.validate_app()
|
app = acl.validate_app()
|
||||||
if not app:
|
if not app:
|
||||||
acl.create_app(payload)
|
acl.create_app(payload)
|
||||||
return acl
|
return acl
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.error(e)
|
||||||
|
if '不存在' in str(e):
|
||||||
|
acl.create_app(payload)
|
||||||
|
return acl
|
||||||
|
raise Exception(e)
|
||||||
|
|
||||||
@staticmethod
|
def get_admin_user_rid(self):
|
||||||
def get_admin_user_rid():
|
|
||||||
admin = Employee.get_by(first=True, username='admin', to_dict=False)
|
admin = Employee.get_by(first=True, username='admin', to_dict=False)
|
||||||
return admin.acl_rid if admin else 0
|
return admin.acl_rid if admin else 0
|
||||||
|
|
||||||
@@ -251,19 +261,17 @@ def common_check_new_columns():
|
|||||||
from api.extensions import db
|
from api.extensions import db
|
||||||
from sqlalchemy import inspect, text
|
from sqlalchemy import inspect, text
|
||||||
|
|
||||||
def get_model_by_table_name(_table_name):
|
def get_model_by_table_name(table_name):
|
||||||
registry = getattr(db.Model, 'registry', None)
|
for model in db.Model.registry._class_registry.values():
|
||||||
class_registry = getattr(registry, '_class_registry', None)
|
if hasattr(model, '__tablename__') and model.__tablename__ == table_name:
|
||||||
for _model in class_registry.values():
|
return model
|
||||||
if hasattr(_model, '__tablename__') and _model.__tablename__ == _table_name:
|
|
||||||
return _model
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def add_new_column(target_table_name, new_column):
|
def add_new_column(table_name, new_column):
|
||||||
column_type = new_column.type.compile(engine.dialect)
|
column_type = new_column.type.compile(engine.dialect)
|
||||||
default_value = new_column.default.arg if new_column.default else None
|
default_value = new_column.default.arg if new_column.default else None
|
||||||
|
|
||||||
sql = "ALTER TABLE " + target_table_name + " ADD COLUMN " + new_column.name + " " + column_type
|
sql = f"ALTER TABLE {table_name} ADD COLUMN {new_column.name} {column_type} "
|
||||||
if new_column.comment:
|
if new_column.comment:
|
||||||
sql += f" comment '{new_column.comment}'"
|
sql += f" comment '{new_column.comment}'"
|
||||||
|
|
||||||
@@ -289,8 +297,7 @@ def common_check_new_columns():
|
|||||||
model = get_model_by_table_name(table_name)
|
model = get_model_by_table_name(table_name)
|
||||||
if model is None:
|
if model is None:
|
||||||
continue
|
continue
|
||||||
|
model_columns = model.__table__.columns._all_columns
|
||||||
model_columns = getattr(getattr(getattr(model, '__table__'), 'columns'), '_all_columns')
|
|
||||||
for column in model_columns:
|
for column in model_columns:
|
||||||
if column.name not in existed_column_name_list:
|
if column.name not in existed_column_name_list:
|
||||||
try:
|
try:
|
||||||
|
@@ -84,6 +84,66 @@ def clean():
|
|||||||
os.remove(full_pathname)
|
os.remove(full_pathname)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
@click.option("--url", default=None, help="Url to test (ex. /static/image.png)")
|
||||||
|
@click.option(
|
||||||
|
"--order", default="rule", help="Property on Rule to order by (default: rule)"
|
||||||
|
)
|
||||||
|
@with_appcontext
|
||||||
|
def urls(url, order):
|
||||||
|
"""Display all of the url matching routes for the project.
|
||||||
|
|
||||||
|
Borrowed from Flask-Script, converted to use Click.
|
||||||
|
"""
|
||||||
|
rows = []
|
||||||
|
column_headers = ("Rule", "Endpoint", "Arguments")
|
||||||
|
|
||||||
|
if url:
|
||||||
|
try:
|
||||||
|
rule, arguments = current_app.url_map.bind("localhost").match(
|
||||||
|
url, return_rule=True
|
||||||
|
)
|
||||||
|
rows.append((rule.rule, rule.endpoint, arguments))
|
||||||
|
column_length = 3
|
||||||
|
except (NotFound, MethodNotAllowed) as e:
|
||||||
|
rows.append(("<{}>".format(e), None, None))
|
||||||
|
column_length = 1
|
||||||
|
else:
|
||||||
|
rules = sorted(
|
||||||
|
current_app.url_map.iter_rules(), key=lambda rule: getattr(rule, order)
|
||||||
|
)
|
||||||
|
for rule in rules:
|
||||||
|
rows.append((rule.rule, rule.endpoint, None))
|
||||||
|
column_length = 2
|
||||||
|
|
||||||
|
str_template = ""
|
||||||
|
table_width = 0
|
||||||
|
|
||||||
|
if column_length >= 1:
|
||||||
|
max_rule_length = max(len(r[0]) for r in rows)
|
||||||
|
max_rule_length = max_rule_length if max_rule_length > 4 else 4
|
||||||
|
str_template += "{:" + str(max_rule_length) + "}"
|
||||||
|
table_width += max_rule_length
|
||||||
|
|
||||||
|
if column_length >= 2:
|
||||||
|
max_endpoint_length = max(len(str(r[1])) for r in rows)
|
||||||
|
max_endpoint_length = max_endpoint_length if max_endpoint_length > 8 else 8
|
||||||
|
str_template += " {:" + str(max_endpoint_length) + "}"
|
||||||
|
table_width += 2 + max_endpoint_length
|
||||||
|
|
||||||
|
if column_length >= 3:
|
||||||
|
max_arguments_length = max(len(str(r[2])) for r in rows)
|
||||||
|
max_arguments_length = max_arguments_length if max_arguments_length > 9 else 9
|
||||||
|
str_template += " {:" + str(max_arguments_length) + "}"
|
||||||
|
table_width += 2 + max_arguments_length
|
||||||
|
|
||||||
|
click.echo(str_template.format(*column_headers[:column_length]))
|
||||||
|
click.echo("-" * table_width)
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
click.echo(str_template.format(*row[:column_length]))
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
@with_appcontext
|
@with_appcontext
|
||||||
def db_setup():
|
def db_setup():
|
||||||
|
@@ -81,9 +81,8 @@ class AttributeManager(object):
|
|||||||
elif choice_other.get('script'):
|
elif choice_other.get('script'):
|
||||||
try:
|
try:
|
||||||
x = compile(choice_other['script'], '', "exec")
|
x = compile(choice_other['script'], '', "exec")
|
||||||
local_ns = {}
|
exec(x)
|
||||||
exec(x, {}, local_ns)
|
res = locals()['ChoiceValue']().values() or []
|
||||||
res = local_ns['ChoiceValue']().values() or []
|
|
||||||
return [[i, {}] for i in res]
|
return [[i, {}] for i in res]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error("get choice values from script: {}".format(e))
|
current_app.logger.error("get choice values from script: {}".format(e))
|
||||||
@@ -337,6 +336,9 @@ class AttributeManager(object):
|
|||||||
def update(self, _id, **kwargs):
|
def update(self, _id, **kwargs):
|
||||||
attr = Attribute.get_by_id(_id) or abort(404, ErrFormat.attribute_not_found.format("id={}".format(_id)))
|
attr = Attribute.get_by_id(_id) or abort(404, ErrFormat.attribute_not_found.format("id={}".format(_id)))
|
||||||
|
|
||||||
|
if not self._can_edit_attribute(attr):
|
||||||
|
return abort(403, ErrFormat.cannot_edit_attribute)
|
||||||
|
|
||||||
if kwargs.get("name"):
|
if kwargs.get("name"):
|
||||||
other = Attribute.get_by(name=kwargs['name'], first=True, to_dict=False)
|
other = Attribute.get_by(name=kwargs['name'], first=True, to_dict=False)
|
||||||
if other and other.id != attr.id:
|
if other and other.id != attr.id:
|
||||||
@@ -377,14 +379,6 @@ class AttributeManager(object):
|
|||||||
|
|
||||||
kwargs.get('is_computed') and self.can_create_computed_attribute()
|
kwargs.get('is_computed') and self.can_create_computed_attribute()
|
||||||
|
|
||||||
is_changed = False
|
|
||||||
for k in kwargs:
|
|
||||||
if kwargs[k] != getattr(attr, k, None):
|
|
||||||
is_changed = True
|
|
||||||
|
|
||||||
if is_changed and not self._can_edit_attribute(attr):
|
|
||||||
return abort(403, ErrFormat.cannot_edit_attribute)
|
|
||||||
|
|
||||||
attr.update(flush=True, filter_none=False, **kwargs)
|
attr.update(flush=True, filter_none=False, **kwargs)
|
||||||
|
|
||||||
if is_choice and choice_value:
|
if is_choice and choice_value:
|
||||||
|
@@ -36,10 +36,9 @@ def parse_plugin_script(script):
|
|||||||
attributes = []
|
attributes = []
|
||||||
try:
|
try:
|
||||||
x = compile(script, '', "exec")
|
x = compile(script, '', "exec")
|
||||||
local_ns = {}
|
exec(x)
|
||||||
exec(x, {}, local_ns)
|
unique_key = locals()['AutoDiscovery']().unique_key
|
||||||
unique_key = local_ns['AutoDiscovery']().unique_key
|
attrs = locals()['AutoDiscovery']().attributes() or []
|
||||||
attrs = local_ns['AutoDiscovery']().attributes() or []
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return abort(400, str(e))
|
return abort(400, str(e))
|
||||||
|
|
||||||
|
@@ -45,8 +45,8 @@ from api.lib.perm.acl.acl import is_app_admin
|
|||||||
from api.lib.perm.acl.acl import validate_permission
|
from api.lib.perm.acl.acl import validate_permission
|
||||||
from api.lib.secrets.inner import InnerCrypt
|
from api.lib.secrets.inner import InnerCrypt
|
||||||
from api.lib.secrets.vault import VaultClient
|
from api.lib.secrets.vault import VaultClient
|
||||||
from api.lib.utils import Lock
|
|
||||||
from api.lib.utils import handle_arg_list
|
from api.lib.utils import handle_arg_list
|
||||||
|
from api.lib.utils import Lock
|
||||||
from api.lib.webhook import webhook_request
|
from api.lib.webhook import webhook_request
|
||||||
from api.models.cmdb import AttributeHistory
|
from api.models.cmdb import AttributeHistory
|
||||||
from api.models.cmdb import AutoDiscoveryCI
|
from api.models.cmdb import AutoDiscoveryCI
|
||||||
@@ -639,9 +639,6 @@ class CIManager(object):
|
|||||||
_fields.append(str(attr.id))
|
_fields.append(str(attr.id))
|
||||||
filter_fields_sql = "WHERE A.attr_id in ({0})".format(",".join(_fields))
|
filter_fields_sql = "WHERE A.attr_id in ({0})".format(",".join(_fields))
|
||||||
|
|
||||||
ci2pos = {int(_id): _pos for _pos, _id in enumerate(ci_ids)}
|
|
||||||
res = [None] * len(ci_ids)
|
|
||||||
|
|
||||||
ci_ids = ",".join(map(str, ci_ids))
|
ci_ids = ",".join(map(str, ci_ids))
|
||||||
if value_tables is None:
|
if value_tables is None:
|
||||||
value_tables = ValueTypeMap.table_name.values()
|
value_tables = ValueTypeMap.table_name.values()
|
||||||
@@ -652,6 +649,7 @@ class CIManager(object):
|
|||||||
# current_app.logger.debug(query_sql)
|
# current_app.logger.debug(query_sql)
|
||||||
cis = db.session.execute(query_sql).fetchall()
|
cis = db.session.execute(query_sql).fetchall()
|
||||||
ci_set = set()
|
ci_set = set()
|
||||||
|
res = list()
|
||||||
ci_dict = dict()
|
ci_dict = dict()
|
||||||
unique_id2obj = dict()
|
unique_id2obj = dict()
|
||||||
excludes = excludes and set(excludes)
|
excludes = excludes and set(excludes)
|
||||||
@@ -671,7 +669,7 @@ class CIManager(object):
|
|||||||
ci_dict["unique"] = unique_id2obj[ci_type.unique_id] and unique_id2obj[ci_type.unique_id].name
|
ci_dict["unique"] = unique_id2obj[ci_type.unique_id] and unique_id2obj[ci_type.unique_id].name
|
||||||
ci_dict["unique_alias"] = unique_id2obj[ci_type.unique_id] and unique_id2obj[ci_type.unique_id].alias
|
ci_dict["unique_alias"] = unique_id2obj[ci_type.unique_id] and unique_id2obj[ci_type.unique_id].alias
|
||||||
ci_set.add(ci_id)
|
ci_set.add(ci_id)
|
||||||
res[ci2pos[ci_id]] = ci_dict
|
res.append(ci_dict)
|
||||||
|
|
||||||
if ret_key == RetKey.NAME:
|
if ret_key == RetKey.NAME:
|
||||||
attr_key = attr_name
|
attr_key = attr_name
|
||||||
|
@@ -9,7 +9,6 @@ import time
|
|||||||
from flask import current_app
|
from flask import current_app
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from jinja2 import Template
|
from jinja2 import Template
|
||||||
from sqlalchemy import text
|
|
||||||
|
|
||||||
from api.extensions import db
|
from api.extensions import db
|
||||||
from api.lib.cmdb.cache import AttributeCache
|
from api.lib.cmdb.cache import AttributeCache
|
||||||
@@ -313,7 +312,7 @@ class Search(object):
|
|||||||
start = time.time()
|
start = time.time()
|
||||||
execute = db.session.execute
|
execute = db.session.execute
|
||||||
# current_app.logger.debug(v_query_sql)
|
# current_app.logger.debug(v_query_sql)
|
||||||
res = execute(text(v_query_sql)).fetchall()
|
res = execute(v_query_sql).fetchall()
|
||||||
end_time = time.time()
|
end_time = time.time()
|
||||||
current_app.logger.debug("query ci ids time is: {0}".format(end_time - start))
|
current_app.logger.debug("query ci ids time is: {0}".format(end_time - start))
|
||||||
|
|
||||||
@@ -526,7 +525,7 @@ class Search(object):
|
|||||||
if k:
|
if k:
|
||||||
table_name = TableMap(attr=attr).table_name
|
table_name = TableMap(attr=attr).table_name
|
||||||
query_sql = FACET_QUERY.format(table_name, self.query_sql, attr.id)
|
query_sql = FACET_QUERY.format(table_name, self.query_sql, attr.id)
|
||||||
result = db.session.execute(text(query_sql)).fetchall()
|
result = db.session.execute(query_sql).fetchall()
|
||||||
facet[k] = result
|
facet[k] = result
|
||||||
|
|
||||||
facet_result = dict()
|
facet_result = dict()
|
||||||
|
@@ -80,22 +80,20 @@ class ACLManager(object):
|
|||||||
return role.to_dict()
|
return role.to_dict()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def delete_role(_id):
|
def delete_role(_id, payload):
|
||||||
RoleCRUD.delete_role(_id)
|
RoleCRUD.delete_role(_id)
|
||||||
return dict(rid=_id)
|
return dict(rid=_id)
|
||||||
|
|
||||||
def get_user_info(self, username):
|
def get_user_info(self, username):
|
||||||
from api.lib.perm.acl.acl import ACLManager as ACL
|
from api.lib.perm.acl.acl import ACLManager as ACL
|
||||||
user_info = ACL().get_user_info(username, self.app_name)
|
user_info = ACL().get_user_info(username, self.app_name)
|
||||||
result = dict(
|
result = dict(name=user_info.get('nickname') or username,
|
||||||
name=user_info.get('nickname') or username,
|
|
||||||
username=user_info.get('username') or username,
|
username=user_info.get('username') or username,
|
||||||
email=user_info.get('email'),
|
email=user_info.get('email'),
|
||||||
uid=user_info.get('uid'),
|
uid=user_info.get('uid'),
|
||||||
rid=user_info.get('rid'),
|
rid=user_info.get('rid'),
|
||||||
role=dict(permissions=user_info.get('parents')),
|
role=dict(permissions=user_info.get('parents')),
|
||||||
avatar=user_info.get('avatar')
|
avatar=user_info.get('avatar'))
|
||||||
)
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# -*- coding:utf-8 -*-
|
# -*- coding:utf-8 -*-
|
||||||
|
|
||||||
from flask import abort, current_app
|
from flask import abort
|
||||||
from treelib import Tree
|
from treelib import Tree
|
||||||
from wtforms import Form
|
from wtforms import Form
|
||||||
from wtforms import IntegerField
|
from wtforms import IntegerField
|
||||||
@@ -9,7 +9,6 @@ from wtforms import validators
|
|||||||
|
|
||||||
from api.extensions import db
|
from api.extensions import db
|
||||||
from api.lib.common_setting.resp_format import ErrFormat
|
from api.lib.common_setting.resp_format import ErrFormat
|
||||||
from api.lib.common_setting.acl import ACLManager
|
|
||||||
from api.lib.perm.acl.role import RoleCRUD
|
from api.lib.perm.acl.role import RoleCRUD
|
||||||
from api.models.common_setting import Department, Employee
|
from api.models.common_setting import Department, Employee
|
||||||
|
|
||||||
@@ -153,10 +152,6 @@ class DepartmentForm(Form):
|
|||||||
|
|
||||||
class DepartmentCRUD(object):
|
class DepartmentCRUD(object):
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_department_by_id(d_id, to_dict=True):
|
|
||||||
return Department.get_by(first=True, department_id=d_id, to_dict=to_dict)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add(**kwargs):
|
def add(**kwargs):
|
||||||
DepartmentCRUD.check_department_name_unique(kwargs['department_name'])
|
DepartmentCRUD.check_department_name_unique(kwargs['department_name'])
|
||||||
@@ -191,11 +186,10 @@ class DepartmentCRUD(object):
|
|||||||
filter(lambda d: d['department_id'] == department_parent_id, allow_p_d_id_list))
|
filter(lambda d: d['department_id'] == department_parent_id, allow_p_d_id_list))
|
||||||
if len(target) == 0:
|
if len(target) == 0:
|
||||||
try:
|
try:
|
||||||
dep = Department.get_by(
|
d = Department.get_by(
|
||||||
first=True, to_dict=False, department_id=department_parent_id)
|
first=True, to_dict=False, department_id=department_parent_id)
|
||||||
name = dep.department_name if dep else ErrFormat.department_id_not_found.format(department_parent_id)
|
name = d.department_name if d else ErrFormat.department_id_not_found.format(department_parent_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(str(e))
|
|
||||||
name = ErrFormat.department_id_not_found.format(department_parent_id)
|
name = ErrFormat.department_id_not_found.format(department_parent_id)
|
||||||
abort(400, ErrFormat.cannot_to_be_parent_department.format(name))
|
abort(400, ErrFormat.cannot_to_be_parent_department.format(name))
|
||||||
|
|
||||||
@@ -259,7 +253,7 @@ class DepartmentCRUD(object):
|
|||||||
try:
|
try:
|
||||||
RoleCRUD.delete_role(existed.acl_rid)
|
RoleCRUD.delete_role(existed.acl_rid)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(str(e))
|
pass
|
||||||
|
|
||||||
return existed.soft_delete()
|
return existed.soft_delete()
|
||||||
|
|
||||||
@@ -274,7 +268,7 @@ class DepartmentCRUD(object):
|
|||||||
try:
|
try:
|
||||||
tree.remove_subtree(department_id)
|
tree.remove_subtree(department_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(str(e))
|
pass
|
||||||
|
|
||||||
[allow_d_id_list.append({'department_id': int(n.identifier), 'department_name': n.tag}) for n in
|
[allow_d_id_list.append({'department_id': int(n.identifier), 'department_name': n.tag}) for n in
|
||||||
tree.all_nodes()]
|
tree.all_nodes()]
|
||||||
@@ -396,125 +390,6 @@ class DepartmentCRUD(object):
|
|||||||
[id_list.append(int(n.identifier))
|
[id_list.append(int(n.identifier))
|
||||||
for n in tmp_tree.all_nodes()]
|
for n in tmp_tree.all_nodes()]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(str(e))
|
pass
|
||||||
|
|
||||||
return id_list
|
return id_list
|
||||||
|
|
||||||
|
|
||||||
class EditDepartmentInACL(object):
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def add_department_to_acl(department_id, op_uid):
|
|
||||||
db_department = DepartmentCRUD.get_department_by_id(department_id, to_dict=False)
|
|
||||||
if not db_department:
|
|
||||||
return
|
|
||||||
|
|
||||||
from api.models.acl import Role
|
|
||||||
role = Role.get_by(first=True, name=db_department.department_name, app_id=None)
|
|
||||||
|
|
||||||
acl = ACLManager('acl', str(op_uid))
|
|
||||||
if role is None:
|
|
||||||
payload = {
|
|
||||||
'app_id': 'acl',
|
|
||||||
'name': db_department.department_name,
|
|
||||||
}
|
|
||||||
role = acl.create_role(payload)
|
|
||||||
|
|
||||||
acl_rid = role.get('id') if role else 0
|
|
||||||
|
|
||||||
db_department.update(
|
|
||||||
acl_rid=acl_rid
|
|
||||||
)
|
|
||||||
info = f"add_department_to_acl, acl_rid: {acl_rid}"
|
|
||||||
current_app.logger.info(info)
|
|
||||||
return info
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def delete_department_from_acl(department_rids, op_uid):
|
|
||||||
acl = ACLManager('acl', str(op_uid))
|
|
||||||
|
|
||||||
result = []
|
|
||||||
|
|
||||||
for rid in department_rids:
|
|
||||||
try:
|
|
||||||
acl.delete_role(rid)
|
|
||||||
except Exception as e:
|
|
||||||
result.append(f"delete_department_in_acl, rid: {rid}, error: {e}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def edit_department_name_in_acl(d_rid: int, d_name: str, op_uid: int):
|
|
||||||
acl = ACLManager('acl', str(op_uid))
|
|
||||||
payload = {
|
|
||||||
'name': d_name
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
acl.edit_role(d_rid, payload)
|
|
||||||
except Exception as e:
|
|
||||||
return f"edit_department_name_in_acl, rid: {d_rid}, error: {e}"
|
|
||||||
|
|
||||||
return f"edit_department_name_in_acl, rid: {d_rid}, success"
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def edit_employee_department_in_acl(e_list: list, new_d_id: int, op_uid: int):
|
|
||||||
result = []
|
|
||||||
new_department = DepartmentCRUD.get_department_by_id(new_d_id, False)
|
|
||||||
if not new_department:
|
|
||||||
result.append(f"{new_d_id} new_department is None")
|
|
||||||
return result
|
|
||||||
|
|
||||||
from api.models.acl import Role
|
|
||||||
new_role = Role.get_by(first=True, name=new_department.department_name, app_id=None)
|
|
||||||
new_d_rid_in_acl = new_role.get('id') if new_role else 0
|
|
||||||
if new_d_rid_in_acl == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
if new_d_rid_in_acl != new_department.acl_rid:
|
|
||||||
new_department.update(
|
|
||||||
acl_rid=new_d_rid_in_acl
|
|
||||||
)
|
|
||||||
new_department_acl_rid = new_department.acl_rid if new_d_rid_in_acl == new_department.acl_rid else \
|
|
||||||
new_d_rid_in_acl
|
|
||||||
|
|
||||||
acl = ACLManager('acl', str(op_uid))
|
|
||||||
for employee in e_list:
|
|
||||||
old_department = DepartmentCRUD.get_department_by_id(employee.get('department_id'), False)
|
|
||||||
if not old_department:
|
|
||||||
continue
|
|
||||||
employee_acl_rid = employee.get('e_acl_rid')
|
|
||||||
if employee_acl_rid == 0:
|
|
||||||
result.append(f"employee_acl_rid == 0")
|
|
||||||
continue
|
|
||||||
|
|
||||||
old_role = Role.get_by(first=True, name=old_department.department_name, app_id=None)
|
|
||||||
old_d_rid_in_acl = old_role.get('id') if old_role else 0
|
|
||||||
if old_d_rid_in_acl == 0:
|
|
||||||
return
|
|
||||||
if old_d_rid_in_acl != old_department.acl_rid:
|
|
||||||
old_department.update(
|
|
||||||
acl_rid=old_d_rid_in_acl
|
|
||||||
)
|
|
||||||
d_acl_rid = old_department.acl_rid if old_d_rid_in_acl == old_department.acl_rid else old_d_rid_in_acl
|
|
||||||
payload = {
|
|
||||||
'app_id': 'acl',
|
|
||||||
'parent_id': d_acl_rid,
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
acl.remove_user_from_role(employee_acl_rid, payload)
|
|
||||||
except Exception as e:
|
|
||||||
result.append(
|
|
||||||
f"remove_user_from_role employee_acl_rid: {employee_acl_rid}, parent_id: {d_acl_rid}, err: {e}")
|
|
||||||
|
|
||||||
payload = {
|
|
||||||
'app_id': 'acl',
|
|
||||||
'child_ids': [employee_acl_rid],
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
acl.add_user_to_role(new_department_acl_rid, payload)
|
|
||||||
except Exception as e:
|
|
||||||
result.append(
|
|
||||||
f"add_user_to_role employee_acl_rid: {employee_acl_rid}, parent_id: {d_acl_rid}, err: {e}")
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
@@ -178,7 +178,7 @@ class EmployeeCRUD(object):
|
|||||||
def edit_employee_by_uid(_uid, **kwargs):
|
def edit_employee_by_uid(_uid, **kwargs):
|
||||||
existed = EmployeeCRUD.get_employee_by_uid(_uid)
|
existed = EmployeeCRUD.get_employee_by_uid(_uid)
|
||||||
try:
|
try:
|
||||||
edit_acl_user(_uid, **kwargs)
|
user = edit_acl_user(_uid, **kwargs)
|
||||||
|
|
||||||
for column in employee_pop_columns:
|
for column in employee_pop_columns:
|
||||||
if kwargs.get(column):
|
if kwargs.get(column):
|
||||||
@@ -190,9 +190,9 @@ class EmployeeCRUD(object):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def change_password_by_uid(_uid, password):
|
def change_password_by_uid(_uid, password):
|
||||||
EmployeeCRUD.get_employee_by_uid(_uid)
|
existed = EmployeeCRUD.get_employee_by_uid(_uid)
|
||||||
try:
|
try:
|
||||||
edit_acl_user(_uid, password=password)
|
user = edit_acl_user(_uid, password=password)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return abort(400, str(e))
|
return abort(400, str(e))
|
||||||
|
|
||||||
@@ -359,11 +359,9 @@ class EmployeeCRUD(object):
|
|||||||
|
|
||||||
if value and column == "last_login":
|
if value and column == "last_login":
|
||||||
try:
|
try:
|
||||||
return datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
|
value = datetime.strptime(value, "%Y-%m-%d %H:%M:%S")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
err = f"{ErrFormat.datetime_format_error.format(column)}: {str(e)}"
|
abort(400, ErrFormat.datetime_format_error.format(column))
|
||||||
abort(400, err)
|
|
||||||
return value
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_attr_by_column(column):
|
def get_attr_by_column(column):
|
||||||
@@ -384,7 +382,7 @@ class EmployeeCRUD(object):
|
|||||||
relation = condition.get("relation", None)
|
relation = condition.get("relation", None)
|
||||||
value = condition.get("value", None)
|
value = condition.get("value", None)
|
||||||
|
|
||||||
value = EmployeeCRUD.check_condition(column, operator, value, relation)
|
EmployeeCRUD.check_condition(column, operator, value, relation)
|
||||||
a, o = EmployeeCRUD.get_expr_by_condition(
|
a, o = EmployeeCRUD.get_expr_by_condition(
|
||||||
column, operator, value, relation)
|
column, operator, value, relation)
|
||||||
and_list += a
|
and_list += a
|
||||||
@@ -567,125 +565,6 @@ class EmployeeCRUD(object):
|
|||||||
results.append(tmp)
|
results.append(tmp)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def import_employee(employee_list):
|
|
||||||
res = CreateEmployee().batch_create(employee_list)
|
|
||||||
return res
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def batch_edit_employee_department(employee_id_list, column_value):
|
|
||||||
err_list = []
|
|
||||||
employee_list = []
|
|
||||||
for _id in employee_id_list:
|
|
||||||
try:
|
|
||||||
existed = EmployeeCRUD.get_employee_by_id(_id)
|
|
||||||
employee = dict(
|
|
||||||
e_acl_rid=existed.acl_rid,
|
|
||||||
department_id=existed.department_id
|
|
||||||
)
|
|
||||||
employee_list.append(employee)
|
|
||||||
existed.update(department_id=column_value)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
err_list.append({
|
|
||||||
'employee_id': _id,
|
|
||||||
'err': str(e),
|
|
||||||
})
|
|
||||||
from api.lib.common_setting.department import EditDepartmentInACL
|
|
||||||
EditDepartmentInACL.edit_employee_department_in_acl(
|
|
||||||
employee_list, column_value, current_user.uid
|
|
||||||
)
|
|
||||||
return err_list
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def batch_edit_password_or_block_column(column_name, employee_id_list, column_value, is_acl=False):
|
|
||||||
if column_name == 'block':
|
|
||||||
err_list = []
|
|
||||||
success_list = []
|
|
||||||
for _id in employee_id_list:
|
|
||||||
try:
|
|
||||||
employee = EmployeeCRUD.edit_employee_block_column(
|
|
||||||
_id, is_acl, **{column_name: column_value})
|
|
||||||
success_list.append(employee)
|
|
||||||
except Exception as e:
|
|
||||||
err_list.append({
|
|
||||||
'employee_id': _id,
|
|
||||||
'err': str(e),
|
|
||||||
})
|
|
||||||
return err_list
|
|
||||||
else:
|
|
||||||
return EmployeeCRUD.batch_edit_column(column_name, employee_id_list, column_value, is_acl)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def batch_edit_column(column_name, employee_id_list, column_value, is_acl=False):
|
|
||||||
err_list = []
|
|
||||||
for _id in employee_id_list:
|
|
||||||
try:
|
|
||||||
EmployeeCRUD.edit_employee_single_column(
|
|
||||||
_id, is_acl, **{column_name: column_value})
|
|
||||||
except Exception as e:
|
|
||||||
err_list.append({
|
|
||||||
'employee_id': _id,
|
|
||||||
'err': str(e),
|
|
||||||
})
|
|
||||||
|
|
||||||
return err_list
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def edit_employee_single_column(_id, is_acl=False, **kwargs):
|
|
||||||
existed = EmployeeCRUD.get_employee_by_id(_id)
|
|
||||||
if 'direct_supervisor_id' in kwargs.keys():
|
|
||||||
if kwargs['direct_supervisor_id'] == existed.direct_supervisor_id:
|
|
||||||
raise Exception(ErrFormat.direct_supervisor_is_not_self)
|
|
||||||
|
|
||||||
if is_acl:
|
|
||||||
return edit_acl_user(existed.acl_uid, **kwargs)
|
|
||||||
|
|
||||||
try:
|
|
||||||
for column in employee_pop_columns:
|
|
||||||
if kwargs.get(column):
|
|
||||||
kwargs.pop(column)
|
|
||||||
|
|
||||||
return existed.update(**kwargs)
|
|
||||||
except Exception as e:
|
|
||||||
return abort(400, str(e))
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def edit_employee_block_column(_id, is_acl=False, **kwargs):
|
|
||||||
existed = EmployeeCRUD.get_employee_by_id(_id)
|
|
||||||
value = get_block_value(kwargs.get('block'))
|
|
||||||
if value is True:
|
|
||||||
check_department_director_id_or_direct_supervisor_id(_id)
|
|
||||||
value = 1
|
|
||||||
else:
|
|
||||||
value = 0
|
|
||||||
|
|
||||||
if is_acl:
|
|
||||||
kwargs['block'] = value
|
|
||||||
edit_acl_user(existed.acl_uid, **kwargs)
|
|
||||||
|
|
||||||
existed.update(block=value)
|
|
||||||
data = existed.to_dict()
|
|
||||||
return data
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def batch_employee(column_name, column_value, employee_id_list):
|
|
||||||
if column_value is None:
|
|
||||||
abort(400, ErrFormat.value_is_required)
|
|
||||||
if column_name in ['password', 'block']:
|
|
||||||
return EmployeeCRUD.batch_edit_password_or_block_column(column_name, employee_id_list, column_value, True)
|
|
||||||
|
|
||||||
elif column_name in ['department_id']:
|
|
||||||
return EmployeeCRUD.batch_edit_employee_department(employee_id_list, column_value)
|
|
||||||
|
|
||||||
elif column_name in [
|
|
||||||
'direct_supervisor_id', 'position_name'
|
|
||||||
]:
|
|
||||||
return EmployeeCRUD.batch_edit_column(column_name, employee_id_list, column_value, False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
abort(400, ErrFormat.column_name_not_support)
|
|
||||||
|
|
||||||
|
|
||||||
def get_user_map(key='uid', acl=None):
|
def get_user_map(key='uid', acl=None):
|
||||||
"""
|
"""
|
||||||
@@ -762,8 +641,7 @@ class CreateEmployee(object):
|
|||||||
**kwargs
|
**kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
def get_department_by_name(self, d_name):
|
||||||
def get_department_by_name(d_name):
|
|
||||||
return Department.get_by(first=True, department_name=d_name)
|
return Department.get_by(first=True, department_name=d_name)
|
||||||
|
|
||||||
def get_end_department_id(self, department_name_list, department_name_map):
|
def get_end_department_id(self, department_name_list, department_name_map):
|
||||||
|
@@ -10,18 +10,14 @@ from api.lib.exception import CommitException
|
|||||||
|
|
||||||
class FormatMixin(object):
|
class FormatMixin(object):
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
res = dict()
|
res = dict([(k, getattr(self, k) if not isinstance(
|
||||||
for k in getattr(self, "__mapper__").c.keys():
|
getattr(self, k), (datetime.datetime, datetime.date, datetime.time)) else str(
|
||||||
if k in {'password', '_password', 'secret', '_secret'}:
|
getattr(self, k))) for k in getattr(self, "__mapper__").c.keys()])
|
||||||
continue
|
# FIXME: getattr(cls, "__table__").columns k.name
|
||||||
|
|
||||||
if k.startswith('_'):
|
res.pop('password', None)
|
||||||
k = k[1:]
|
res.pop('_password', None)
|
||||||
|
res.pop('secret', None)
|
||||||
if not isinstance(getattr(self, k), (datetime.datetime, datetime.date, datetime.time)):
|
|
||||||
res[k] = getattr(self, k)
|
|
||||||
else:
|
|
||||||
res[k] = str(getattr(self, k))
|
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
@@ -276,6 +276,7 @@ class ResourceCRUD(object):
|
|||||||
|
|
||||||
from api.tasks.acl import apply_trigger
|
from api.tasks.acl import apply_trigger
|
||||||
triggers = TriggerCRUD.match_triggers(app_id, r.name, r.resource_type_id, uid)
|
triggers = TriggerCRUD.match_triggers(app_id, r.name, r.resource_type_id, uid)
|
||||||
|
current_app.logger.info(triggers)
|
||||||
for trigger in triggers:
|
for trigger in triggers:
|
||||||
# auto trigger should be no uid
|
# auto trigger should be no uid
|
||||||
apply_trigger.apply_async(args=(trigger.id,),
|
apply_trigger.apply_async(args=(trigger.id,),
|
||||||
|
@@ -65,8 +65,7 @@ class KeyManage:
|
|||||||
self.backend = Backend(backend)
|
self.backend = Backend(backend)
|
||||||
|
|
||||||
def init_app(self, app, backend=None):
|
def init_app(self, app, backend=None):
|
||||||
if (sys.argv[0].endswith("gunicorn") or
|
if sys.argv[0].endswith("gunicorn") or (len(sys.argv) > 1 and sys.argv[1] == "run"):
|
||||||
(len(sys.argv) > 1 and sys.argv[1] in ("run", "cmdb-password-data-migrate"))):
|
|
||||||
self.trigger = app.config.get("INNER_TRIGGER_TOKEN")
|
self.trigger = app.config.get("INNER_TRIGGER_TOKEN")
|
||||||
if not self.trigger:
|
if not self.trigger:
|
||||||
return
|
return
|
||||||
|
@@ -12,9 +12,6 @@ from Crypto.Cipher import AES
|
|||||||
from elasticsearch import Elasticsearch
|
from elasticsearch import Elasticsearch
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
|
||||||
from api.lib.secrets.inner import InnerCrypt
|
|
||||||
from api.lib.secrets.inner import KeyManage
|
|
||||||
|
|
||||||
|
|
||||||
class BaseEnum(object):
|
class BaseEnum(object):
|
||||||
_ALL_ = set() # type: Set[str]
|
_ALL_ = set() # type: Set[str]
|
||||||
@@ -289,33 +286,3 @@ class AESCrypto(object):
|
|||||||
text_decrypted = cipher.decrypt(encode_bytes)
|
text_decrypted = cipher.decrypt(encode_bytes)
|
||||||
|
|
||||||
return cls.unpad(text_decrypted).decode('utf8')
|
return cls.unpad(text_decrypted).decode('utf8')
|
||||||
|
|
||||||
|
|
||||||
class Crypto(AESCrypto):
|
|
||||||
@classmethod
|
|
||||||
def encrypt(cls, data):
|
|
||||||
from api.lib.secrets.secrets import InnerKVManger
|
|
||||||
|
|
||||||
if not KeyManage(backend=InnerKVManger()).is_seal():
|
|
||||||
res, status = InnerCrypt().encrypt(data)
|
|
||||||
if status:
|
|
||||||
return res
|
|
||||||
|
|
||||||
return AESCrypto().encrypt(data)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def decrypt(cls, data):
|
|
||||||
from api.lib.secrets.secrets import InnerKVManger
|
|
||||||
|
|
||||||
if not KeyManage(backend=InnerKVManger()).is_seal():
|
|
||||||
try:
|
|
||||||
res, status = InnerCrypt().decrypt(data)
|
|
||||||
if status:
|
|
||||||
return res
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
return AESCrypto().decrypt(data)
|
|
||||||
except:
|
|
||||||
return data
|
|
||||||
|
@@ -12,9 +12,7 @@ from api.lib.cmdb.const import CITypeOperateType
|
|||||||
from api.lib.cmdb.const import ConstraintEnum
|
from api.lib.cmdb.const import ConstraintEnum
|
||||||
from api.lib.cmdb.const import OperateType
|
from api.lib.cmdb.const import OperateType
|
||||||
from api.lib.cmdb.const import ValueTypeEnum
|
from api.lib.cmdb.const import ValueTypeEnum
|
||||||
from api.lib.database import Model
|
from api.lib.database import Model, Model2
|
||||||
from api.lib.database import Model2
|
|
||||||
from api.lib.utils import Crypto
|
|
||||||
|
|
||||||
|
|
||||||
# template
|
# template
|
||||||
@@ -91,37 +89,13 @@ class Attribute(Model):
|
|||||||
compute_expr = db.Column(db.Text)
|
compute_expr = db.Column(db.Text)
|
||||||
compute_script = db.Column(db.Text)
|
compute_script = db.Column(db.Text)
|
||||||
|
|
||||||
_choice_web_hook = db.Column('choice_web_hook', db.JSON)
|
choice_web_hook = db.Column(db.JSON)
|
||||||
choice_other = db.Column(db.JSON)
|
choice_other = db.Column(db.JSON)
|
||||||
|
|
||||||
uid = db.Column(db.Integer, index=True)
|
uid = db.Column(db.Integer, index=True)
|
||||||
|
|
||||||
option = db.Column(db.JSON)
|
option = db.Column(db.JSON)
|
||||||
|
|
||||||
def _get_webhook(self):
|
|
||||||
if self._choice_web_hook:
|
|
||||||
if self._choice_web_hook.get('headers') and "Cookie" in self._choice_web_hook['headers']:
|
|
||||||
self._choice_web_hook['headers']['Cookie'] = Crypto.decrypt(self._choice_web_hook['headers']['Cookie'])
|
|
||||||
|
|
||||||
if self._choice_web_hook.get('authorization'):
|
|
||||||
for k, v in self._choice_web_hook['authorization'].items():
|
|
||||||
self._choice_web_hook['authorization'][k] = Crypto.decrypt(v)
|
|
||||||
|
|
||||||
return self._choice_web_hook
|
|
||||||
|
|
||||||
def _set_webhook(self, data):
|
|
||||||
if data:
|
|
||||||
if data.get('headers') and "Cookie" in data['headers']:
|
|
||||||
data['headers']['Cookie'] = Crypto.encrypt(data['headers']['Cookie'])
|
|
||||||
|
|
||||||
if data.get('authorization'):
|
|
||||||
for k, v in data['authorization'].items():
|
|
||||||
data['authorization'][k] = Crypto.encrypt(v)
|
|
||||||
|
|
||||||
self._choice_web_hook = data
|
|
||||||
|
|
||||||
choice_web_hook = db.synonym("_choice_web_hook", descriptor=property(_get_webhook, _set_webhook))
|
|
||||||
|
|
||||||
|
|
||||||
class CITypeAttribute(Model):
|
class CITypeAttribute(Model):
|
||||||
__tablename__ = "c_ci_type_attributes"
|
__tablename__ = "c_ci_type_attributes"
|
||||||
@@ -156,25 +130,7 @@ class CITypeTrigger(Model):
|
|||||||
|
|
||||||
type_id = db.Column(db.Integer, db.ForeignKey('c_ci_types.id'), nullable=False)
|
type_id = db.Column(db.Integer, db.ForeignKey('c_ci_types.id'), nullable=False)
|
||||||
attr_id = db.Column(db.Integer, db.ForeignKey("c_attributes.id"))
|
attr_id = db.Column(db.Integer, db.ForeignKey("c_attributes.id"))
|
||||||
_option = db.Column('notify', db.JSON)
|
option = db.Column('notify', db.JSON)
|
||||||
|
|
||||||
def _get_option(self):
|
|
||||||
if self._option and self._option.get('webhooks'):
|
|
||||||
if self._option['webhooks'].get('authorization'):
|
|
||||||
for k, v in self._option['webhooks']['authorization'].items():
|
|
||||||
self._option['webhooks']['authorization'][k] = Crypto.decrypt(v)
|
|
||||||
|
|
||||||
return self._option
|
|
||||||
|
|
||||||
def _set_option(self, data):
|
|
||||||
if data and data.get('webhooks'):
|
|
||||||
if data['webhooks'].get('authorization'):
|
|
||||||
for k, v in data['webhooks']['authorization'].items():
|
|
||||||
data['webhooks']['authorization'][k] = Crypto.encrypt(v)
|
|
||||||
|
|
||||||
self._option = data
|
|
||||||
|
|
||||||
option = db.synonym("_option", descriptor=property(_get_option, _set_option))
|
|
||||||
|
|
||||||
|
|
||||||
class CITriggerHistory(Model):
|
class CITriggerHistory(Model):
|
||||||
|
@@ -24,12 +24,12 @@ class DataView(APIView):
|
|||||||
class DataViewWithId(APIView):
|
class DataViewWithId(APIView):
|
||||||
url_prefix = (f'{prefix}/<string:data_type>/<int:_id>',)
|
url_prefix = (f'{prefix}/<string:data_type>/<int:_id>',)
|
||||||
|
|
||||||
def put(self, _id):
|
def put(self, data_type, _id):
|
||||||
params = request.json
|
params = request.json
|
||||||
res = CommonDataCRUD.update_data(_id, **params)
|
res = CommonDataCRUD.update_data(_id, **params)
|
||||||
|
|
||||||
return self.jsonify(res.to_dict())
|
return self.jsonify(res.to_dict())
|
||||||
|
|
||||||
def delete(self, _id):
|
def delete(self, data_type, _id):
|
||||||
CommonDataCRUD.delete(_id)
|
CommonDataCRUD.delete(_id)
|
||||||
return self.jsonify({})
|
return self.jsonify({})
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
# -*- coding:utf-8 -*-
|
# -*- coding:utf-8 -*-
|
||||||
|
from flask import abort
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
from api.lib.common_setting.company_info import CompanyInfoCRUD
|
from api.lib.common_setting.company_info import CompanyInfoCRUD
|
||||||
|
from api.lib.common_setting.resp_format import ErrFormat
|
||||||
from api.resource import APIView
|
from api.resource import APIView
|
||||||
|
|
||||||
prefix = '/company'
|
prefix = '/company'
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
# -*- coding:utf-8 -*-
|
# -*- coding:utf-8 -*-
|
||||||
from flask import abort
|
import os
|
||||||
|
|
||||||
|
from flask import abort, current_app, send_from_directory
|
||||||
from flask import request
|
from flask import request
|
||||||
from werkzeug.datastructures import MultiDict
|
from werkzeug.datastructures import MultiDict
|
||||||
|
|
||||||
|
@@ -47,7 +47,7 @@ class CheckEmailServer(APIView):
|
|||||||
|
|
||||||
def post(self):
|
def post(self):
|
||||||
receive_address = request.args.get('receive_address')
|
receive_address = request.args.get('receive_address')
|
||||||
info = request.values.get('info', {})
|
info = request.values.get('info')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@ Flask==2.3.2
|
|||||||
Flask-Bcrypt==1.0.1
|
Flask-Bcrypt==1.0.1
|
||||||
Flask-Caching==2.0.2
|
Flask-Caching==2.0.2
|
||||||
Flask-Cors==4.0.0
|
Flask-Cors==4.0.0
|
||||||
Flask-Login>=0.6.2
|
Flask-Login==0.6.2
|
||||||
Flask-Migrate==2.5.2
|
Flask-Migrate==2.5.2
|
||||||
Flask-RESTful==0.3.10
|
Flask-RESTful==0.3.10
|
||||||
Flask-SQLAlchemy==2.5.0
|
Flask-SQLAlchemy==2.5.0
|
||||||
@@ -29,8 +29,8 @@ MarkupSafe==2.1.3
|
|||||||
marshmallow==2.20.2
|
marshmallow==2.20.2
|
||||||
more-itertools==5.0.0
|
more-itertools==5.0.0
|
||||||
msgpack-python==0.5.6
|
msgpack-python==0.5.6
|
||||||
Pillow>=10.0.1
|
Pillow==9.3.0
|
||||||
cryptography>=41.0.2
|
cryptography==41.0.2
|
||||||
PyJWT==2.4.0
|
PyJWT==2.4.0
|
||||||
PyMySQL==1.1.0
|
PyMySQL==1.1.0
|
||||||
ldap3==2.9.1
|
ldap3==2.9.1
|
||||||
@@ -45,7 +45,7 @@ supervisor==4.0.3
|
|||||||
timeout-decorator==0.5.0
|
timeout-decorator==0.5.0
|
||||||
toposort==1.10
|
toposort==1.10
|
||||||
treelib==1.6.1
|
treelib==1.6.1
|
||||||
Werkzeug>=2.3.6
|
Werkzeug==2.3.6
|
||||||
WTForms==3.0.0
|
WTForms==3.0.0
|
||||||
shamir~=17.12.0
|
shamir~=17.12.0
|
||||||
hvac~=2.0.0
|
hvac~=2.0.0
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
"@wangeditor/editor": "^5.1.23",
|
"@wangeditor/editor": "^5.1.23",
|
||||||
"@wangeditor/editor-for-vue": "^1.0.0",
|
"@wangeditor/editor-for-vue": "^1.0.0",
|
||||||
"ant-design-vue": "^1.6.5",
|
"ant-design-vue": "^1.6.5",
|
||||||
"axios": "1.6.0",
|
"axios": "0.18.0",
|
||||||
"babel-eslint": "^8.2.2",
|
"babel-eslint": "^8.2.2",
|
||||||
"butterfly-dag": "^4.3.26",
|
"butterfly-dag": "^4.3.26",
|
||||||
"codemirror": "^5.65.13",
|
"codemirror": "^5.65.13",
|
||||||
@@ -63,15 +63,14 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ant-design/colors": "^3.2.2",
|
"@ant-design/colors": "^3.2.2",
|
||||||
"@babel/core": "^7.23.2",
|
|
||||||
"@babel/polyfill": "^7.2.5",
|
"@babel/polyfill": "^7.2.5",
|
||||||
"@babel/preset-env": "^7.23.2",
|
|
||||||
"@vue/cli-plugin-babel": "4.5.17",
|
"@vue/cli-plugin-babel": "4.5.17",
|
||||||
"@vue/cli-plugin-eslint": "^4.0.5",
|
"@vue/cli-plugin-eslint": "^4.0.5",
|
||||||
"@vue/cli-plugin-unit-jest": "^4.0.5",
|
"@vue/cli-plugin-unit-jest": "^4.0.5",
|
||||||
"@vue/cli-service": "^4.0.5",
|
"@vue/cli-service": "^4.0.5",
|
||||||
"@vue/eslint-config-standard": "^4.0.0",
|
"@vue/eslint-config-standard": "^4.0.0",
|
||||||
"@vue/test-utils": "^1.0.0-beta.30",
|
"@vue/test-utils": "^1.0.0-beta.30",
|
||||||
|
"babel-core": "7.0.0-bridge.0",
|
||||||
"babel-jest": "^23.6.0",
|
"babel-jest": "^23.6.0",
|
||||||
"babel-plugin-import": "^1.11.0",
|
"babel-plugin-import": "^1.11.0",
|
||||||
"babel-plugin-transform-remove-console": "^6.9.4",
|
"babel-plugin-transform-remove-console": "^6.9.4",
|
||||||
|
14023
cmdb-ui/yarn.lock
Normal file
14023
cmdb-ui/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -239,6 +239,11 @@ CREATE TABLE `acl_operation_records` (
|
|||||||
-- Dumping data for table `acl_operation_records`
|
-- Dumping data for table `acl_operation_records`
|
||||||
--
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `acl_operation_records` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `acl_operation_records` DISABLE KEYS */;
|
||||||
|
INSERT INTO `acl_operation_records` VALUES (NULL,0,'2023-07-11 16:48:37',NULL,11,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 16:49:09',NULL,12,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 16:49:21',NULL,13,NULL,'admin','0','[\"ACL\"]'),(NULL,0,'2023-07-11 16:49:22',NULL,14,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 16:50:38',NULL,15,NULL,'admin','0','[\"ACL\"]'),(NULL,0,'2023-07-11 16:50:38',NULL,16,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 16:57:53',NULL,17,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:08:22',NULL,18,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:12:20',NULL,19,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:12:24',NULL,20,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:13:11',NULL,21,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:15:17',NULL,22,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:22:31',NULL,23,NULL,'admin','0','[\"ACL\"]'),(NULL,0,'2023-07-11 17:22:31',NULL,24,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:27:19',NULL,25,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:28:49',NULL,26,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:36:06',NULL,27,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:36:10',NULL,28,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:37:06',NULL,29,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:39:05',NULL,30,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:39:10',NULL,31,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:46:52',NULL,32,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 17:54:00',NULL,33,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 18:03:56',NULL,34,NULL,'admin','0','[\"ACL\"]'),(NULL,0,'2023-07-11 18:03:56',NULL,35,'backend','cmdb_agent','1','[\"resources\"]'),(NULL,0,'2023-07-11 18:03:57',NULL,36,'backend','cmdb_agent','1','[\"resources\"]');
|
||||||
|
/*!40000 ALTER TABLE `acl_operation_records` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `acl_permissions`
|
-- Table structure for table `acl_permissions`
|
||||||
@@ -654,6 +659,12 @@ CREATE TABLE `c_ad_ci_types` (
|
|||||||
-- Dumping data for table `c_ad_ci_types`
|
-- Dumping data for table `c_ad_ci_types`
|
||||||
--
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `c_ad_ci_types` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `c_ad_ci_types` DISABLE KEYS */;
|
||||||
|
INSERT INTO `c_ad_ci_types` VALUES (NULL,0,'2023-07-11 17:11:52',NULL,2,4,9,NULL,NULL,0,NULL,NULL,300,NULL,NULL,1),(NULL,0,'2023-07-11 17:19:23','2023-07-11 17:19:25',3,5,10,'{}',NULL,0,'','',300,NULL,NULL,1);
|
||||||
|
/*!40000 ALTER TABLE `c_ad_ci_types` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `c_ad_rules`
|
-- Table structure for table `c_ad_rules`
|
||||||
--
|
--
|
||||||
@@ -2237,7 +2248,7 @@ CREATE TABLE `users` (
|
|||||||
|
|
||||||
LOCK TABLES `users` WRITE;
|
LOCK TABLES `users` WRITE;
|
||||||
/*!40000 ALTER TABLE `users` DISABLE KEYS */;
|
/*!40000 ALTER TABLE `users` DISABLE KEYS */;
|
||||||
INSERT INTO `users` VALUES (NULL,0,1,'admin','admin',NULL,NULL,'admin@one-ops.com',NULL,'e10adc3949ba59abbe56e057f20f883e','','',NULL,'2023-07-11 18:03:55',0,1,NULL,'0001',NULL,NULL),(NULL,0,2,'cmdb_agent','cmdb_agent',NULL,NULL,'cmdb_agent@one-ops.com',NULL,NULL,'ef086550acb543828d9930d15b21a037','U~83O&PT2Qxsd1$H9df2v#*FcsiG1l?n',NULL,NULL,0,NULL,NULL,'0002',NULL,NULL),(NULL,0,3,'worker','worker',NULL,NULL,'worker@one-ops.com',NULL,'b34cd51b4a6e2f96547e4aeb81566a83','0577dfa24e4547ad91bfb23b62951845','~0g7tkFG$@wdHKe*r2rYu2RC2v1?d8I5',NULL,NULL,0,NULL,NULL,'0003',NULL,NULL),(NULL,0,46,'demo','demo',NULL,NULL,'demo@veops.cn',NULL,'e10adc3949ba59abbe56e057f20f883e','0ec692fb318b47e4b739c241d56c12e7','JDcAc563I4L47ji2R?fah1dZ6KPb!Ty0','2023-07-10 08:19:01','2023-07-11 16:30:42',0,1,NULL,'0004',NULL,NULL);
|
INSERT INTO `users` VALUES (NULL,0,1,'admin','admin',NULL,NULL,'admin@one-ops.com',NULL,'e10adc3949ba59abbe56e057f20f883e','','',NULL,'2023-07-11 18:03:55',0,1,NULL,'0000',NULL,NULL),(NULL,0,2,'cmdb_agent','cmdb_agent',NULL,NULL,'cmdb_agent@one-ops.com',NULL,NULL,'ef086550acb543828d9930d15b21a037','U~83O&PT2Qxsd1$H9df2v#*FcsiG1l?n',NULL,NULL,0,NULL,NULL,NULL,NULL,NULL),(NULL,0,3,'worker','worker',NULL,NULL,'worker@one-ops.com',NULL,'b34cd51b4a6e2f96547e4aeb81566a83','0577dfa24e4547ad91bfb23b62951845','~0g7tkFG$@wdHKe*r2rYu2RC2v1?d8I5',NULL,NULL,0,NULL,NULL,NULL,NULL,NULL),(NULL,0,46,'demo','demo',NULL,NULL,'demo@veops.cn',NULL,'e10adc3949ba59abbe56e057f20f883e','0ec692fb318b47e4b739c241d56c12e7','JDcAc563I4L47ji2R?fah1dZ6KPb!Ty0','2023-07-10 08:19:01','2023-07-11 16:30:42',0,1,NULL,'0036',NULL,NULL);
|
||||||
/*!40000 ALTER TABLE `users` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `users` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||||
|
Reference in New Issue
Block a user