Merge branch 'master' into fix_deploy_1700028675

This commit is contained in:
fxiang21 2023-11-22 18:24:28 +08:00
commit 628c15fe4f
14 changed files with 155 additions and 14212 deletions

1
.gitignore vendored
View File

@ -70,6 +70,7 @@ 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*

View File

@ -1,6 +1,8 @@
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
@ -23,50 +25,18 @@ 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 acl_clean(): def add_user():
# from api.models.acl import Resource """
# from api.models.acl import Permission create a user
# from api.models.acl import RolePermission
# is_admin: default is False
# perms = RolePermission.get_by(to_dict=False)
# """
# for r in perms:
# perm = Permission.get_by_id(r.perm_id) username = click.prompt('Enter username', confirmation_prompt=False)
# if perm and perm.app_id != r.app_id: password = click.prompt('Enter password', hide_input=True, confirmation_prompt=True)
# resource_id = r.resource_id email = click.prompt('Enter email ', confirmation_prompt=False)
# resource = Resource.get_by_id(resource_id)
# perm_name = perm.name UserCRUD.add(username=username, password=password, email=email)
# 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)

View File

@ -29,7 +29,6 @@ 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
@ -128,10 +127,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)
type_id = ResourceType.get_by(name=ResourceTypeEnum.CI, first=True, to_dict=False).id resource_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, type_id, app_id) ResourceCRUD.add(ci_type.name, resource_type_id, app_id)
except AbortException: except AbortException:
pass pass
@ -141,10 +140,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)
type_id = ResourceType.get_by(name=ResourceTypeEnum.RELATION_VIEW, first=True, to_dict=False).id resource_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, type_id, app_id) ResourceCRUD.add(view.name, resource_type_id, app_id)
except AbortException: except AbortException:
pass pass
@ -154,57 +153,6 @@ 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():
@ -474,3 +422,39 @@ def cmdb_password_data_migrate():
if not failed and attr.is_index: if not failed and attr.is_index:
attr.update(is_index=False) 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')))

View File

@ -84,66 +84,6 @@ 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():

View File

@ -10,14 +10,18 @@ from api.lib.exception import CommitException
class FormatMixin(object): class FormatMixin(object):
def to_dict(self): def to_dict(self):
res = dict([(k, getattr(self, k) if not isinstance( res = dict()
getattr(self, k), (datetime.datetime, datetime.date, datetime.time)) else str( for k in getattr(self, "__mapper__").c.keys():
getattr(self, k))) for k in getattr(self, "__mapper__").c.keys()]) if k in {'password', '_password', 'secret', '_secret'}:
# FIXME: getattr(cls, "__table__").columns k.name continue
res.pop('password', None) if k.startswith('_'):
res.pop('_password', None) k = k[1:]
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

View File

@ -276,7 +276,6 @@ 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,),

View File

@ -12,6 +12,9 @@ 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]
@ -286,3 +289,33 @@ 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

View File

@ -12,7 +12,9 @@ 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, Model2 from api.lib.database import Model
from api.lib.database import Model2
from api.lib.utils import Crypto
# template # template
@ -89,13 +91,37 @@ 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(db.JSON) _choice_web_hook = db.Column('choice_web_hook', 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"
@ -130,7 +156,25 @@ 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):

View File

@ -63,14 +63,15 @@
}, },
"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",

View File

@ -68,6 +68,7 @@
ref="xTable" ref="xTable"
row-id="id" row-id="id"
show-overflow show-overflow
resizable
> >
<!-- 1 --> <!-- 1 -->
<vxe-table-column type="checkbox" fixed="left" :width="45"></vxe-table-column> <vxe-table-column type="checkbox" fixed="left" :width="45"></vxe-table-column>

File diff suppressed because it is too large Load Diff

View File

@ -239,11 +239,6 @@ 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`
@ -659,12 +654,6 @@ 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`
-- --
@ -2248,7 +2237,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,'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); 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);
/*!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 */;

View File

@ -22,7 +22,7 @@ cp cmdb-api/settings.example.py cmdb-api/settings.py
- 后端: `cd cmdb-api && pipenv run pipenv install && cd ..` - 后端: `cd cmdb-api && pipenv run pipenv install && cd ..`
- 前端: `cd cmdb-ui && yarn install && cd ..` - 前端: `cd cmdb-ui && yarn install && cd ..`
- 可以将 docs/cmdb.sql 导入到数据库里,登录用户和密码分别是:demo/123456 - 可以将 docs/cmdb.sql 导入到数据库里,登录用户和密码分别是:demo/123456
- 创建数据库表: 进入**cmdb-api**目录执行 `pipenv run flask db-setup && pipenv run flask cmdb-init-cache` - 创建数据库表: 进入**cmdb-api**目录执行 `pipenv run flask db-setup && pipenv run flask common-check-new-columns && pipenv run flask cmdb-init-cache`
- 启动服务 - 启动服务
- 后端: 进入**cmdb-api**目录执行 `pipenv run flask run -h 0.0.0.0` - 后端: 进入**cmdb-api**目录执行 `pipenv run flask run -h 0.0.0.0`

View File

@ -17,7 +17,7 @@
- frontend: `cd cmdb-ui && yarn install && cd ..` - frontend: `cd cmdb-ui && yarn install && cd ..`
- Suggest step: (default: user:demo,password:123456) - Suggest step: (default: user:demo,password:123456)
- Create tables of cmdb database: - Create tables of cmdb database:
in **cmdb-api** directory: `pipenv run flask db-setup && pipenv run flask cmdb-init-cache` in **cmdb-api** directory: `pipenv run flask db-setup && pipenv run flask common-check-new-columns && pipenv run flask cmdb-init-cache`
` source docs/cmdb.sql` ` source docs/cmdb.sql`