mirror of
				https://github.com/veops/cmdb.git
				synced 2025-10-31 19:39:24 +08:00 
			
		
		
		
	Merge branch 'master' of github.com:veops/cmdb into dev_ui
This commit is contained in:
		.gitignore
cmdb-api/api
app.py
lib
cmdb
attribute.py
auto_discovery
cache.pyci.pyci_type.pyconst.pyhistory.pypreference.pyrelation_type.pysearch
value.pycommon_setting
decorator.pyperm
utils.pymodels
resource.pytasks
views
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -39,6 +39,7 @@ pip-log.txt | ||||
| nosetests.xml | ||||
| .pytest_cache | ||||
| cmdb-api/test-output | ||||
| cmdb-api/api/uploaded_files | ||||
|  | ||||
| # Translations | ||||
| *.mo | ||||
|   | ||||
| @@ -9,7 +9,8 @@ from inspect import getmembers | ||||
| from logging.handlers import RotatingFileHandler | ||||
|  | ||||
| from flask import Flask | ||||
| from flask import jsonify, make_response | ||||
| from flask import jsonify | ||||
| from flask import make_response | ||||
| from flask.blueprints import Blueprint | ||||
| from flask.cli import click | ||||
| from flask.json.provider import DefaultJSONProvider | ||||
|   | ||||
| @@ -10,8 +10,11 @@ from api.extensions import db | ||||
| from api.lib.cmdb.cache import AttributeCache | ||||
| from api.lib.cmdb.cache import CITypeAttributesCache | ||||
| from api.lib.cmdb.cache import CITypeCache | ||||
| from api.lib.cmdb.const import BUILTIN_KEYWORDS | ||||
| from api.lib.cmdb.const import CITypeOperateType | ||||
| from api.lib.cmdb.const import PermEnum, ResourceTypeEnum, RoleEnum | ||||
| from api.lib.cmdb.const import PermEnum | ||||
| from api.lib.cmdb.const import ResourceTypeEnum | ||||
| from api.lib.cmdb.const import RoleEnum | ||||
| from api.lib.cmdb.const import ValueTypeEnum | ||||
| from api.lib.cmdb.history import CITypeHistoryManager | ||||
| from api.lib.cmdb.resp_format import ErrFormat | ||||
| @@ -41,7 +44,7 @@ class AttributeManager(object): | ||||
|         ret_key = choice_web_hook.get('ret_key') | ||||
|         headers = choice_web_hook.get('headers') or {} | ||||
|         payload = choice_web_hook.get('payload') or {} | ||||
|         method = choice_web_hook.get('method', 'GET').lower() | ||||
|         method = (choice_web_hook.get('method') or 'GET').lower() | ||||
|  | ||||
|         try: | ||||
|             res = getattr(requests, method)(url, headers=headers, data=payload).json() | ||||
| @@ -56,15 +59,17 @@ class AttributeManager(object): | ||||
|                 return [[i, {}] for i in (res.get(ret_key_list[-1]) or [])] | ||||
|  | ||||
|         except Exception as e: | ||||
|             current_app.logger.error(str(e)) | ||||
|             current_app.logger.error("get choice values failed: {}".format(e)) | ||||
|             return [] | ||||
|  | ||||
|     @classmethod | ||||
|     def get_choice_values(cls, attr_id, value_type, choice_web_hook, choice_web_hook_parse=True): | ||||
|         if choice_web_hook and isinstance(choice_web_hook, dict) and choice_web_hook_parse: | ||||
|             return cls._get_choice_values_from_web_hook(choice_web_hook) | ||||
|         elif choice_web_hook and not choice_web_hook_parse: | ||||
|             return [] | ||||
|         if choice_web_hook: | ||||
|             if choice_web_hook_parse: | ||||
|                 if isinstance(choice_web_hook, dict): | ||||
|                     return cls._get_choice_values_from_web_hook(choice_web_hook) | ||||
|             else: | ||||
|                 return [] | ||||
|  | ||||
|         choice_table = ValueTypeMap.choice.get(value_type) | ||||
|         choice_values = choice_table.get_by(fl=["value", "option"], attr_id=attr_id) | ||||
| @@ -74,25 +79,25 @@ class AttributeManager(object): | ||||
|     @staticmethod | ||||
|     def add_choice_values(_id, value_type, choice_values): | ||||
|         choice_table = ValueTypeMap.choice.get(value_type) | ||||
|         if choice_table is None: | ||||
|             return | ||||
|  | ||||
|         choice_table.get_by(attr_id=_id, only_query=True).delete() | ||||
|  | ||||
|         db.session.query(choice_table).filter(choice_table.attr_id == _id).delete() | ||||
|         db.session.flush() | ||||
|         choice_values = choice_values | ||||
|         for v, option in choice_values: | ||||
|             table = choice_table(attr_id=_id, value=v, option=option) | ||||
|  | ||||
|             db.session.add(table) | ||||
|             choice_table.create(attr_id=_id, value=v, option=option, commit=False) | ||||
|  | ||||
|         try: | ||||
|             db.session.flush() | ||||
|         except: | ||||
|         except Exception as e: | ||||
|             current_app.logger.warning("add choice values failed: {}".format(e)) | ||||
|             return abort(400, ErrFormat.invalid_choice_values) | ||||
|  | ||||
|     @staticmethod | ||||
|     def _del_choice_values(_id, value_type): | ||||
|         choice_table = ValueTypeMap.choice.get(value_type) | ||||
|  | ||||
|         db.session.query(choice_table).filter(choice_table.attr_id == _id).delete() | ||||
|         choice_table and choice_table.get_by(attr_id=_id, only_query=True).delete() | ||||
|         db.session.flush() | ||||
|  | ||||
|     @classmethod | ||||
| @@ -115,8 +120,8 @@ class AttributeManager(object): | ||||
|         attrs = attrs[(page - 1) * page_size:][:page_size] | ||||
|         res = list() | ||||
|         for attr in attrs: | ||||
|             attr["is_choice"] and attr.update(dict(choice_value=cls.get_choice_values( | ||||
|                 attr["id"], attr["value_type"], attr["choice_web_hook"]))) | ||||
|             attr["is_choice"] and attr.update( | ||||
|                 dict(choice_value=cls.get_choice_values(attr["id"], attr["value_type"], attr["choice_web_hook"]))) | ||||
|             attr['is_choice'] and attr.pop('choice_web_hook', None) | ||||
|  | ||||
|             res.append(attr) | ||||
| @@ -125,30 +130,31 @@ class AttributeManager(object): | ||||
|  | ||||
|     def get_attribute_by_name(self, name): | ||||
|         attr = Attribute.get_by(name=name, first=True) | ||||
|         if attr and attr["is_choice"]: | ||||
|             attr.update(dict(choice_value=self.get_choice_values( | ||||
|                 attr["id"], attr["value_type"], attr["choice_web_hook"]))) | ||||
|         if attr.get("is_choice"): | ||||
|             attr["choice_value"] = self.get_choice_values(attr["id"], attr["value_type"], attr["choice_web_hook"]) | ||||
|  | ||||
|         return attr | ||||
|  | ||||
|     def get_attribute_by_alias(self, alias): | ||||
|         attr = Attribute.get_by(alias=alias, first=True) | ||||
|         if attr and attr["is_choice"]: | ||||
|             attr.update(dict(choice_value=self.get_choice_values( | ||||
|                 attr["id"], attr["value_type"], attr["choice_web_hook"]))) | ||||
|         if attr.get("is_choice"): | ||||
|             attr["choice_value"] = self.get_choice_values(attr["id"], attr["value_type"], attr["choice_web_hook"]) | ||||
|  | ||||
|         return attr | ||||
|  | ||||
|     def get_attribute_by_id(self, _id): | ||||
|         attr = Attribute.get_by_id(_id).to_dict() | ||||
|         if attr and attr["is_choice"]: | ||||
|             attr.update(dict(choice_value=self.get_choice_values( | ||||
|                 attr["id"], attr["value_type"], attr["choice_web_hook"]))) | ||||
|         if attr.get("is_choice"): | ||||
|             attr["choice_value"] = self.get_choice_values(attr["id"], attr["value_type"], attr["choice_web_hook"]) | ||||
|  | ||||
|         return attr | ||||
|  | ||||
|     def get_attribute(self, key, choice_web_hook_parse=True): | ||||
|         attr = AttributeCache.get(key).to_dict() | ||||
|         if attr and attr["is_choice"]: | ||||
|             attr.update(dict(choice_value=self.get_choice_values( | ||||
|                 attr["id"], attr["value_type"], attr["choice_web_hook"])), choice_web_hook_parse=choice_web_hook_parse) | ||||
|         if attr.get("is_choice"): | ||||
|             attr["choice_value"] = self.get_choice_values( | ||||
|                 attr["id"], attr["value_type"], attr["choice_web_hook"], choice_web_hook_parse=choice_web_hook_parse) | ||||
|  | ||||
|         return attr | ||||
|  | ||||
|     @staticmethod | ||||
| @@ -164,8 +170,9 @@ class AttributeManager(object): | ||||
|         is_choice = True if choice_value or kwargs.get('choice_web_hook') else False | ||||
|  | ||||
|         name = kwargs.pop("name") | ||||
|         if name in {'id', '_id', 'ci_id', 'type', '_type', 'ci_type'}: | ||||
|         if name in BUILTIN_KEYWORDS: | ||||
|             return abort(400, ErrFormat.attribute_name_cannot_be_builtin) | ||||
|  | ||||
|         alias = kwargs.pop("alias", "") | ||||
|         alias = name if not alias else alias | ||||
|         Attribute.get_by(name=name, first=True) and abort(400, ErrFormat.attribute_name_duplicate.format(name)) | ||||
| @@ -218,7 +225,8 @@ class AttributeManager(object): | ||||
|         for i in CITypeAttribute.get_by(attr_id=attr_id, to_dict=False): | ||||
|             CITypeAttributesCache.clean(i.type_id) | ||||
|  | ||||
|     def _change_index(self, attr, old, new): | ||||
|     @staticmethod | ||||
|     def _change_index(attr, old, new): | ||||
|         from api.lib.cmdb.utils import TableMap | ||||
|         from api.tasks.cmdb import batch_ci_cache | ||||
|         from api.lib.cmdb.const import CMDB_QUEUE | ||||
| @@ -227,11 +235,11 @@ class AttributeManager(object): | ||||
|         new_table = TableMap(attr=attr, is_index=new).table | ||||
|  | ||||
|         ci_ids = [] | ||||
|         for i in db.session.query(old_table).filter(getattr(old_table, 'attr_id') == attr.id): | ||||
|         for i in old_table.get_by(attr_id=attr.id, to_dict=False): | ||||
|             new_table.create(ci_id=i.ci_id, attr_id=attr.id, value=i.value, flush=True) | ||||
|             ci_ids.append(i.ci_id) | ||||
|  | ||||
|         db.session.query(old_table).filter(getattr(old_table, 'attr_id') == attr.id).delete() | ||||
|         old_table.get_by(attr_id=attr.id, only_query=True).delete() | ||||
|  | ||||
|         try: | ||||
|             db.session.commit() | ||||
| @@ -296,7 +304,7 @@ class AttributeManager(object): | ||||
|  | ||||
|         if is_choice and choice_value: | ||||
|             self.add_choice_values(attr.id, attr.value_type, choice_value) | ||||
|         elif is_choice: | ||||
|         elif existed2['is_choice']: | ||||
|             self._del_choice_values(attr.id, attr.value_type) | ||||
|  | ||||
|         try: | ||||
| @@ -330,24 +338,25 @@ class AttributeManager(object): | ||||
|         ref = CITypeAttribute.get_by(attr_id=_id, to_dict=False, first=True) | ||||
|         if ref is not None: | ||||
|             ci_type = CITypeCache.get(ref.type_id) | ||||
|             return abort(400, ErrFormat.attribute_is_ref_by_type.format(ci_type.alias)) | ||||
|             return abort(400, ErrFormat.attribute_is_ref_by_type.format(ci_type and ci_type.alias or ref.type_id)) | ||||
|  | ||||
|         if attr.uid != current_user.uid and not is_app_admin('cmdb'): | ||||
|             return abort(403, ErrFormat.cannot_delete_attribute) | ||||
|  | ||||
|         if attr.is_choice: | ||||
|             choice_table = ValueTypeMap.choice.get(attr.value_type) | ||||
|             db.session.query(choice_table).filter(choice_table.attr_id == _id).delete()  # FIXME: session conflict | ||||
|             db.session.flush() | ||||
|  | ||||
|         AttributeCache.clean(attr) | ||||
|             choice_table.get_by(attr_id=_id, only_query=True).delete() | ||||
|  | ||||
|         attr.soft_delete() | ||||
|  | ||||
|         AttributeCache.clean(attr) | ||||
|  | ||||
|         for i in PreferenceShowAttributes.get_by(attr_id=_id, to_dict=False): | ||||
|             i.soft_delete() | ||||
|             i.soft_delete(commit=False) | ||||
|  | ||||
|         for i in CITypeAttributeGroupItem.get_by(attr_id=_id, to_dict=False): | ||||
|             i.soft_delete() | ||||
|             i.soft_delete(commit=False) | ||||
|  | ||||
|         db.session.commit() | ||||
|  | ||||
|         return name | ||||
|   | ||||
| @@ -240,9 +240,10 @@ class AutoDiscoveryCITypeCRUD(DBMixin): | ||||
|             try: | ||||
|                 response, _, _, _, _, _ = s.search() | ||||
|                 for i in response: | ||||
|                     if current_user.username not in (i.get('rd_duty') or []) and current_user.username not in \ | ||||
|                             (i.get('op_duty') or []) and current_user.nickname not in (i.get('rd_duty') or []) and \ | ||||
|                             current_user.nickname not in (i.get('op_duty') or []): | ||||
|                     if (current_user.username not in (i.get('rd_duty') or []) and | ||||
|                             current_user.username not in (i.get('op_duty') or []) and | ||||
|                             current_user.nickname not in (i.get('rd_duty') or []) and | ||||
|                             current_user.nickname not in (i.get('op_duty') or [])): | ||||
|                         return abort(403, ErrFormat.adt_target_expr_no_permission.format( | ||||
|                             i.get("{}_name".format(i.get('ci_type'))))) | ||||
|             except SearchError as e: | ||||
|   | ||||
| @@ -34,6 +34,7 @@ class AttributeCache(object): | ||||
|             attr = attr or Attribute.get_by(alias=key, first=True, to_dict=False) | ||||
|             if attr is not None: | ||||
|                 cls.set(attr) | ||||
|  | ||||
|         return attr | ||||
|  | ||||
|     @classmethod | ||||
| @@ -67,6 +68,7 @@ class CITypeCache(object): | ||||
|             ct = ct or CIType.get_by(alias=key, first=True, to_dict=False) | ||||
|             if ct is not None: | ||||
|                 cls.set(ct) | ||||
|  | ||||
|         return ct | ||||
|  | ||||
|     @classmethod | ||||
| @@ -98,6 +100,7 @@ class RelationTypeCache(object): | ||||
|             ct = RelationType.get_by(name=key, first=True, to_dict=False) or RelationType.get_by_id(key) | ||||
|             if ct is not None: | ||||
|                 cls.set(ct) | ||||
|  | ||||
|         return ct | ||||
|  | ||||
|     @classmethod | ||||
| @@ -133,12 +136,15 @@ class CITypeAttributesCache(object): | ||||
|         attrs = attrs or cache.get(cls.PREFIX_ID.format(key)) | ||||
|         if not attrs: | ||||
|             attrs = CITypeAttribute.get_by(type_id=key, to_dict=False) | ||||
|  | ||||
|             if not attrs: | ||||
|                 ci_type = CIType.get_by(name=key, first=True, to_dict=False) | ||||
|                 if ci_type is not None: | ||||
|                     attrs = CITypeAttribute.get_by(type_id=ci_type.id, to_dict=False) | ||||
|  | ||||
|             if attrs is not None: | ||||
|                 cls.set(key, attrs) | ||||
|  | ||||
|         return attrs | ||||
|  | ||||
|     @classmethod | ||||
| @@ -155,13 +161,16 @@ class CITypeAttributesCache(object): | ||||
|         attrs = attrs or cache.get(cls.PREFIX_ID2.format(key)) | ||||
|         if not attrs: | ||||
|             attrs = CITypeAttribute.get_by(type_id=key, to_dict=False) | ||||
|  | ||||
|             if not attrs: | ||||
|                 ci_type = CIType.get_by(name=key, first=True, to_dict=False) | ||||
|                 if ci_type is not None: | ||||
|                     attrs = CITypeAttribute.get_by(type_id=ci_type.id, to_dict=False) | ||||
|  | ||||
|             if attrs is not None: | ||||
|                 attrs = [(i, AttributeCache.get(i.attr_id)) for i in attrs] | ||||
|                 cls.set2(key, attrs) | ||||
|  | ||||
|         return attrs | ||||
|  | ||||
|     @classmethod | ||||
| @@ -204,10 +213,11 @@ class CITypeAttributeCache(object): | ||||
|  | ||||
|         attr = cache.get(cls.PREFIX_ID.format(type_id, attr_id)) | ||||
|         attr = attr or cache.get(cls.PREFIX_ID.format(type_id, attr_id)) | ||||
|         if not attr: | ||||
|             attr = CITypeAttribute.get_by(type_id=type_id, attr_id=attr_id, first=True, to_dict=False) | ||||
|             if attr is not None: | ||||
|                 cls.set(type_id, attr_id, attr) | ||||
|         attr = attr or CITypeAttribute.get_by(type_id=type_id, attr_id=attr_id, first=True, to_dict=False) | ||||
|  | ||||
|         if attr is not None: | ||||
|             cls.set(type_id, attr_id, attr) | ||||
|  | ||||
|         return attr | ||||
|  | ||||
|     @classmethod | ||||
|   | ||||
| @@ -38,8 +38,8 @@ from api.lib.decorator import kwargs_required | ||||
| from api.lib.perm.acl.acl import ACLManager | ||||
| from api.lib.perm.acl.acl import is_app_admin | ||||
| from api.lib.perm.acl.acl import validate_permission | ||||
| from api.lib.utils import Lock | ||||
| from api.lib.utils import handle_arg_list | ||||
| from api.lib.utils import Lock | ||||
| from api.models.cmdb import AutoDiscoveryCI | ||||
| from api.models.cmdb import CI | ||||
| from api.models.cmdb import CIRelation | ||||
| @@ -67,11 +67,13 @@ class CIManager(object): | ||||
|     @staticmethod | ||||
|     def get_type_name(ci_id): | ||||
|         ci = CI.get_by_id(ci_id) or abort(404, ErrFormat.ci_not_found.format("id={}".format(ci_id))) | ||||
|  | ||||
|         return CITypeCache.get(ci.type_id).name | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_type(ci_id): | ||||
|         ci = CI.get_by_id(ci_id) or abort(404, ErrFormat.ci_not_found.format("id={}".format(ci_id))) | ||||
|  | ||||
|         return CITypeCache.get(ci.type_id) | ||||
|  | ||||
|     @staticmethod | ||||
| @@ -93,9 +95,7 @@ class CIManager(object): | ||||
|  | ||||
|         res = dict() | ||||
|  | ||||
|         if need_children: | ||||
|             children = CIRelationManager.get_children(ci_id, ret_key=ret_key)  # one floor | ||||
|             res.update(children) | ||||
|         need_children and res.update(CIRelationManager.get_children(ci_id, ret_key=ret_key))  # one floor | ||||
|  | ||||
|         ci_type = CITypeCache.get(ci.type_id) | ||||
|         res["ci_type"] = ci_type.name | ||||
| @@ -162,14 +162,11 @@ class CIManager(object): | ||||
|  | ||||
|         ci = CI.get_by_id(ci_id) or abort(404, ErrFormat.ci_not_found.format("id={}".format(ci_id))) | ||||
|  | ||||
|         if valid: | ||||
|             cls.valid_ci_only_read(ci) | ||||
|         valid and cls.valid_ci_only_read(ci) | ||||
|  | ||||
|         res = dict() | ||||
|  | ||||
|         if need_children: | ||||
|             children = CIRelationManager.get_children(ci_id, ret_key=ret_key)  # one floor | ||||
|             res.update(children) | ||||
|         need_children and res.update(CIRelationManager.get_children(ci_id, ret_key=ret_key))  # one floor | ||||
|  | ||||
|         ci_type = CITypeCache.get(ci.type_id) | ||||
|         res["ci_type"] = ci_type.name | ||||
| @@ -248,7 +245,7 @@ class CIManager(object): | ||||
|         for i in unique_constraints: | ||||
|             attr_ids.extend(i.attr_ids) | ||||
|  | ||||
|         attrs = [AttributeCache.get(i) for i in list(set(attr_ids))] | ||||
|         attrs = [AttributeCache.get(i) for i in set(attr_ids)] | ||||
|         id2name = {i.id: i.name for i in attrs if i} | ||||
|         not_existed_fields = list(set(id2name.values()) - set(ci_dict.keys())) | ||||
|         if not_existed_fields and ci_id is not None: | ||||
| @@ -333,10 +330,6 @@ class CIManager(object): | ||||
|                 if exist_policy == ExistPolicy.NEED: | ||||
|                     return abort(404, ErrFormat.ci_not_found.format("{}={}".format(unique_key.name, unique_value))) | ||||
|  | ||||
|                 from api.lib.cmdb.const import L_CI | ||||
|                 if L_CI and len(CI.get_by(type_id=ci_type.id)) > L_CI * 2: | ||||
|                     return abort(400, ErrFormat.limit_ci.format(L_CI * 2)) | ||||
|  | ||||
|             limit_attrs = cls._valid_ci_for_no_read(ci, ci_type) if not _is_admin else {} | ||||
|  | ||||
|             if existed is None:  # set default | ||||
| @@ -368,12 +361,12 @@ class CIManager(object): | ||||
|             cls._valid_unique_constraint(ci_type.id, ci_dict, ci and ci.id) | ||||
|  | ||||
|             for k in ci_dict: | ||||
|                 if k not in ci_type_attrs_name and k not in ci_type_attrs_alias and \ | ||||
|                         _no_attribute_policy == ExistPolicy.REJECT: | ||||
|                 if k not in ci_type_attrs_name and ( | ||||
|                         k not in ci_type_attrs_alias and _no_attribute_policy == ExistPolicy.REJECT): | ||||
|                     return abort(400, ErrFormat.attribute_not_found.format(k)) | ||||
|  | ||||
|                 if limit_attrs and ci_type_attrs_name.get(k) not in limit_attrs and \ | ||||
|                         ci_type_attrs_alias.get(k) not in limit_attrs: | ||||
|                 if limit_attrs and ci_type_attrs_name.get(k) not in limit_attrs and ( | ||||
|                         ci_type_attrs_alias.get(k) not in limit_attrs): | ||||
|                     return abort(403, ErrFormat.ci_filter_perm_attr_no_permission.format(k)) | ||||
|  | ||||
|             ci_dict = {k: v for k, v in ci_dict.items() if k in ci_type_attrs_name or k in ci_type_attrs_alias} | ||||
| @@ -486,11 +479,11 @@ class CIManager(object): | ||||
|         unique_key = AttributeCache.get(ci_type.unique_id) | ||||
|         value_table = TableMap(attr=unique_key).table | ||||
|  | ||||
|         v = value_table.get_by(attr_id=unique_key.id, | ||||
|         v = (value_table.get_by(attr_id=unique_key.id, | ||||
|                                value=unique_value, | ||||
|                                to_dict=False, | ||||
|                                first=True) \ | ||||
|             or abort(404, ErrFormat.not_found) | ||||
|                                first=True) or | ||||
|              abort(404, ErrFormat.not_found)) | ||||
|  | ||||
|         ci = CI.get_by_id(v.ci_id) or abort(404, ErrFormat.ci_not_found.format("id={}".format(v.ci_id))) | ||||
|  | ||||
| @@ -536,6 +529,7 @@ class CIManager(object): | ||||
|         result = [(i.get("hostname"), i.get("private_ip")[0], i.get("ci_type"), | ||||
|                    heartbeat_dict.get(i.get("_id"))) for i in res | ||||
|                   if i.get("private_ip")] | ||||
|  | ||||
|         return numfound, result | ||||
|  | ||||
|     @staticmethod | ||||
| @@ -655,6 +649,7 @@ class CIManager(object): | ||||
|             return res | ||||
|  | ||||
|         current_app.logger.warning("cache not hit...............") | ||||
|  | ||||
|         return cls._get_cis_from_db(ci_ids, ret_key, fields, value_tables, excludes=excludes) | ||||
|  | ||||
|  | ||||
| @@ -680,6 +675,7 @@ class CIRelationManager(object): | ||||
|             ci_type = CITypeCache.get(type_id) | ||||
|             children = CIManager.get_cis_by_ids(list(map(str, ci_type2ci_ids[type_id])), ret_key=ret_key) | ||||
|             res[ci_type.name] = children | ||||
|  | ||||
|         return res | ||||
|  | ||||
|     @staticmethod | ||||
| @@ -856,12 +852,12 @@ class CIRelationManager(object): | ||||
|         :param children: | ||||
|         :return: | ||||
|         """ | ||||
|         if parents is not None and isinstance(parents, list): | ||||
|         if isinstance(parents, list): | ||||
|             for parent_id in parents: | ||||
|                 for ci_id in ci_ids: | ||||
|                     cls.add(parent_id, ci_id) | ||||
|  | ||||
|         if children is not None and isinstance(children, list): | ||||
|         if isinstance(children, list): | ||||
|             for child_id in children: | ||||
|                 for ci_id in ci_ids: | ||||
|                     cls.add(ci_id, child_id) | ||||
| @@ -875,7 +871,7 @@ class CIRelationManager(object): | ||||
|         :return: | ||||
|         """ | ||||
|  | ||||
|         if parents is not None and isinstance(parents, list): | ||||
|         if isinstance(parents, list): | ||||
|             for parent_id in parents: | ||||
|                 for ci_id in ci_ids: | ||||
|                     cls.delete_2(parent_id, ci_id) | ||||
|   | ||||
| @@ -16,7 +16,9 @@ from api.lib.cmdb.cache import CITypeCache | ||||
| from api.lib.cmdb.const import CITypeOperateType | ||||
| from api.lib.cmdb.const import CMDB_QUEUE | ||||
| from api.lib.cmdb.const import ConstraintEnum | ||||
| from api.lib.cmdb.const import PermEnum, ResourceTypeEnum, RoleEnum | ||||
| from api.lib.cmdb.const import PermEnum | ||||
| from api.lib.cmdb.const import ResourceTypeEnum | ||||
| from api.lib.cmdb.const import RoleEnum | ||||
| from api.lib.cmdb.const import ValueTypeEnum | ||||
| from api.lib.cmdb.history import CITypeHistoryManager | ||||
| from api.lib.cmdb.relation_type import RelationTypeManager | ||||
| @@ -60,6 +62,7 @@ class CITypeManager(object): | ||||
|     @staticmethod | ||||
|     def get_name_by_id(type_id): | ||||
|         ci_type = CITypeCache.get(type_id) | ||||
|  | ||||
|         return ci_type and ci_type.name | ||||
|  | ||||
|     @staticmethod | ||||
| @@ -71,7 +74,7 @@ class CITypeManager(object): | ||||
|     @staticmethod | ||||
|     def get_ci_types(type_name=None): | ||||
|         resources = None | ||||
|         if current_app.config.get('USE_ACL') and not is_app_admin(): | ||||
|         if current_app.config.get('USE_ACL') and not is_app_admin('cmdb'): | ||||
|             resources = set([i.get('name') for i in ACLManager().get_resources("CIType")]) | ||||
|  | ||||
|         ci_types = CIType.get_by() if type_name is None else CIType.get_by_like(name=type_name) | ||||
| @@ -110,9 +113,6 @@ class CITypeManager(object): | ||||
|     @classmethod | ||||
|     @kwargs_required("name") | ||||
|     def add(cls, **kwargs): | ||||
|         from api.lib.cmdb.const import L_TYPE | ||||
|         if L_TYPE and len(CIType.get_by()) > L_TYPE * 2: | ||||
|             return abort(400, ErrFormat.limit_ci_type.format(L_TYPE * 2)) | ||||
|  | ||||
|         unique_key = kwargs.pop("unique_key", None) | ||||
|         unique_key = AttributeCache.get(unique_key) or abort(404, ErrFormat.unique_key_not_define) | ||||
| @@ -184,6 +184,7 @@ class CITypeManager(object): | ||||
|     def set_enabled(cls, type_id, enabled=True): | ||||
|         ci_type = cls.check_is_existed(type_id) | ||||
|         ci_type.update(enabled=enabled) | ||||
|  | ||||
|         return type_id | ||||
|  | ||||
|     @classmethod | ||||
| @@ -268,6 +269,7 @@ class CITypeGroupManager(object): | ||||
|     @staticmethod | ||||
|     def add(name): | ||||
|         CITypeGroup.get_by(name=name, first=True) and abort(400, ErrFormat.ci_type_group_exists.format(name)) | ||||
|  | ||||
|         return CITypeGroup.create(name=name) | ||||
|  | ||||
|     @staticmethod | ||||
| @@ -354,6 +356,7 @@ class CITypeAttributeManager(object): | ||||
|                 attr_dict.pop('choice_web_hook', None) | ||||
|  | ||||
|             result.append(attr_dict) | ||||
|  | ||||
|         return result | ||||
|  | ||||
|     @staticmethod | ||||
| @@ -541,6 +544,7 @@ class CITypeRelationManager(object): | ||||
|         ci_type_dict["attributes"] = CITypeAttributeManager.get_attributes_by_type_id(ci_type_dict["id"]) | ||||
|         ci_type_dict["relation_type"] = relation_inst.relation_type.name | ||||
|         ci_type_dict["constraint"] = relation_inst.constraint | ||||
|  | ||||
|         return ci_type_dict | ||||
|  | ||||
|     @classmethod | ||||
| @@ -599,8 +603,8 @@ class CITypeRelationManager(object): | ||||
|  | ||||
|     @classmethod | ||||
|     def delete(cls, _id): | ||||
|         ctr = CITypeRelation.get_by_id(_id) or \ | ||||
|               abort(404, ErrFormat.ci_type_relation_not_found.format("id={}".format(_id))) | ||||
|         ctr = (CITypeRelation.get_by_id(_id) or | ||||
|                abort(404, ErrFormat.ci_type_relation_not_found.format("id={}".format(_id)))) | ||||
|         ctr.soft_delete() | ||||
|  | ||||
|         CITypeHistoryManager.add(CITypeOperateType.DELETE_RELATION, ctr.parent_id, | ||||
| @@ -654,6 +658,7 @@ class CITypeAttributeGroupManager(object): | ||||
|         :param name: | ||||
|         :param group_order: group order | ||||
|         :param attr_order: | ||||
|         :param is_update: | ||||
|         :return: | ||||
|         """ | ||||
|         existed = CITypeAttributeGroup.get_by(type_id=type_id, name=name, first=True, to_dict=False) | ||||
| @@ -694,8 +699,8 @@ class CITypeAttributeGroupManager(object): | ||||
|  | ||||
|     @staticmethod | ||||
|     def delete(group_id): | ||||
|         group = CITypeAttributeGroup.get_by_id(group_id) \ | ||||
|                 or abort(404, ErrFormat.ci_type_attribute_group_not_found.format("id={}".format(group_id))) | ||||
|         group = (CITypeAttributeGroup.get_by_id(group_id) or | ||||
|                  abort(404, ErrFormat.ci_type_attribute_group_not_found.format("id={}".format(group_id)))) | ||||
|         group.soft_delete() | ||||
|  | ||||
|         items = CITypeAttributeGroupItem.get_by(group_id=group_id, to_dict=False) | ||||
| @@ -964,8 +969,8 @@ class CITypeTemplateManager(object): | ||||
|             rule['uid'] = current_user.uid | ||||
|             try: | ||||
|                 AutoDiscoveryCITypeCRUD.add(**rule) | ||||
|             except: | ||||
|                 pass | ||||
|             except Exception as e: | ||||
|                 current_app.logger.warning("import auto discovery rules failed: {}".format(e)) | ||||
|  | ||||
|     def import_template(self, tpt): | ||||
|         import time | ||||
| @@ -1124,8 +1129,8 @@ class CITypeTriggerManager(object): | ||||
|  | ||||
|     @staticmethod | ||||
|     def update(_id, notify): | ||||
|         existed = CITypeTrigger.get_by_id(_id) or \ | ||||
|                   abort(404, ErrFormat.ci_type_trigger_not_found.format("id={}".format(_id))) | ||||
|         existed = (CITypeTrigger.get_by_id(_id) or | ||||
|                    abort(404, ErrFormat.ci_type_trigger_not_found.format("id={}".format(_id)))) | ||||
|  | ||||
|         existed2 = existed.to_dict() | ||||
|         new = existed.update(notify=notify) | ||||
| @@ -1139,8 +1144,8 @@ class CITypeTriggerManager(object): | ||||
|  | ||||
|     @staticmethod | ||||
|     def delete(_id): | ||||
|         existed = CITypeTrigger.get_by_id(_id) or \ | ||||
|                   abort(404, ErrFormat.ci_type_trigger_not_found.format("id={}".format(_id))) | ||||
|         existed = (CITypeTrigger.get_by_id(_id) or | ||||
|                    abort(404, ErrFormat.ci_type_trigger_not_found.format("id={}".format(_id)))) | ||||
|  | ||||
|         existed.soft_delete() | ||||
|  | ||||
| @@ -1163,16 +1168,16 @@ class CITypeTriggerManager(object): | ||||
|  | ||||
|         result = [] | ||||
|         for v in values: | ||||
|             if isinstance(v.value, (datetime.date, datetime.datetime)) and \ | ||||
|                     (v.value - delta_time).strftime('%Y%m%d') == now.strftime("%Y%m%d"): | ||||
|             if (isinstance(v.value, (datetime.date, datetime.datetime)) and | ||||
|                     (v.value - delta_time).strftime('%Y%m%d') == now.strftime("%Y%m%d")): | ||||
|                 result.append(v) | ||||
|  | ||||
|         return result | ||||
|  | ||||
|     @staticmethod | ||||
|     def trigger_notify(trigger, ci): | ||||
|         if trigger.notify.get('notify_at') == datetime.datetime.now().strftime("%H:%M") or \ | ||||
|                 not trigger.notify.get('notify_at'): | ||||
|         if (trigger.notify.get('notify_at') == datetime.datetime.now().strftime("%H:%M") or | ||||
|                 not trigger.notify.get('notify_at')): | ||||
|             from api.tasks.cmdb import trigger_notify | ||||
|  | ||||
|             trigger_notify.apply_async(args=(trigger.notify, ci.ci_id), queue=CMDB_QUEUE) | ||||
|   | ||||
| @@ -99,5 +99,7 @@ CMDB_QUEUE = "one_cmdb_async" | ||||
| REDIS_PREFIX_CI = "ONE_CMDB" | ||||
| REDIS_PREFIX_CI_RELATION = "CMDB_CI_RELATION" | ||||
|  | ||||
| BUILTIN_KEYWORDS = {'id', '_id', 'ci_id', 'type', '_type', 'ci_type'} | ||||
|  | ||||
| L_TYPE = None | ||||
| L_CI = None | ||||
|   | ||||
| @@ -176,8 +176,8 @@ class AttributeHistoryManger(object): | ||||
|     def get_record_detail(record_id): | ||||
|         from api.lib.cmdb.ci import CIManager | ||||
|  | ||||
|         record = OperationRecord.get_by_id(record_id) or \ | ||||
|                  abort(404, ErrFormat.record_not_found.format("id={}".format(record_id))) | ||||
|         record = (OperationRecord.get_by_id(record_id) or | ||||
|                   abort(404, ErrFormat.record_not_found.format("id={}".format(record_id)))) | ||||
|  | ||||
|         username = UserCache.get(record.uid).nickname or UserCache.get(record.uid).username | ||||
|         timestamp = record.created_at.strftime("%Y-%m-%d %H:%M:%S") | ||||
|   | ||||
| @@ -37,10 +37,12 @@ class PreferenceManager(object): | ||||
|     def get_types(instance=False, tree=False): | ||||
|         types = db.session.query(PreferenceShowAttributes.type_id).filter( | ||||
|             PreferenceShowAttributes.uid == current_user.uid).filter( | ||||
|             PreferenceShowAttributes.deleted.is_(False)).group_by(PreferenceShowAttributes.type_id).all() \ | ||||
|             if instance else [] | ||||
|             PreferenceShowAttributes.deleted.is_(False)).group_by( | ||||
|             PreferenceShowAttributes.type_id).all() if instance else [] | ||||
|  | ||||
|         tree_types = PreferenceTreeView.get_by(uid=current_user.uid, to_dict=False) if tree else [] | ||||
|         type_ids = list(set([i.type_id for i in types + tree_types])) | ||||
|         type_ids = set([i.type_id for i in types + tree_types]) | ||||
|  | ||||
|         return [CITypeCache.get(type_id).to_dict() for type_id in type_ids] | ||||
|  | ||||
|     @staticmethod | ||||
|   | ||||
| @@ -24,21 +24,21 @@ class RelationTypeManager(object): | ||||
|  | ||||
|     @staticmethod | ||||
|     def add(name): | ||||
|         RelationType.get_by(name=name, first=True, to_dict=False) and \ | ||||
|         abort(400, ErrFormat.relation_type_exists.format(name)) | ||||
|         RelationType.get_by(name=name, first=True, to_dict=False) and abort( | ||||
|             400, ErrFormat.relation_type_exists.format(name)) | ||||
|  | ||||
|         return RelationType.create(name=name) | ||||
|  | ||||
|     @staticmethod | ||||
|     def update(rel_id, name): | ||||
|         existed = RelationType.get_by_id(rel_id) or \ | ||||
|                   abort(404, ErrFormat.relation_type_not_found.format("id={}".format(rel_id))) | ||||
|         existed = RelationType.get_by_id(rel_id) or abort( | ||||
|             404, ErrFormat.relation_type_not_found.format("id={}".format(rel_id))) | ||||
|  | ||||
|         return existed.update(name=name) | ||||
|  | ||||
|     @staticmethod | ||||
|     def delete(rel_id): | ||||
|         existed = RelationType.get_by_id(rel_id) or \ | ||||
|                   abort(404, ErrFormat.relation_type_not_found.format("id={}".format(rel_id))) | ||||
|         existed = RelationType.get_by_id(rel_id) or abort( | ||||
|             404, ErrFormat.relation_type_not_found.format("id={}".format(rel_id))) | ||||
|  | ||||
|         existed.soft_delete() | ||||
|   | ||||
| @@ -245,10 +245,8 @@ class Search(object): | ||||
|         new_table = _v_query_sql | ||||
|  | ||||
|         if self.only_type_query or not self.type_id_list: | ||||
|             return "SELECT SQL_CALC_FOUND_ROWS DISTINCT C.ci_id " \ | ||||
|                    "FROM ({0}) AS C " \ | ||||
|                    "ORDER BY C.value {2} " \ | ||||
|                    "LIMIT {1:d}, {3};".format(new_table, (self.page - 1) * self.count, sort_type, self.count) | ||||
|             return ("SELECT SQL_CALC_FOUND_ROWS DISTINCT C.ci_id FROM ({0}) AS C ORDER BY C.value {2} " | ||||
|                     "LIMIT {1:d}, {3};".format(new_table, (self.page - 1) * self.count, sort_type, self.count)) | ||||
|  | ||||
|         elif self.type_id_list: | ||||
|             self.query_sql = """SELECT C.ci_id | ||||
|   | ||||
| @@ -297,8 +297,8 @@ class Search(object): | ||||
|             if not attr: | ||||
|                 raise SearchError(ErrFormat.attribute_not_found.format(field)) | ||||
|  | ||||
|             sort_by = "{0}.keyword".format(field) \ | ||||
|                 if attr.value_type not in (ValueTypeEnum.INT, ValueTypeEnum.FLOAT) else field | ||||
|             sort_by = ("{0}.keyword".format(field) | ||||
|                        if attr.value_type not in (ValueTypeEnum.INT, ValueTypeEnum.FLOAT) else field) | ||||
|             sorts.append({sort_by: {"order": sort_type}}) | ||||
|  | ||||
|         self.query.update(dict(sort=sorts)) | ||||
|   | ||||
| @@ -83,6 +83,7 @@ class AttributeValueManager(object): | ||||
|     def __deserialize_value(value_type, value): | ||||
|         if not value: | ||||
|             return value | ||||
|  | ||||
|         deserialize = ValueTypeMap.deserialize[value_type] | ||||
|         try: | ||||
|             v = deserialize(value) | ||||
| @@ -184,8 +185,8 @@ class AttributeValueManager(object): | ||||
|         return [var for var in schema.get("properties")] | ||||
|  | ||||
|     def _compute_attr_value(self, attr, payload, ci): | ||||
|         attrs = self._jinja2_parse(attr['compute_expr']) if attr.get('compute_expr') else \ | ||||
|             self._jinja2_parse(attr['compute_script']) | ||||
|         attrs = (self._jinja2_parse(attr['compute_expr']) if attr.get('compute_expr') | ||||
|                  else self._jinja2_parse(attr['compute_script'])) | ||||
|         not_existed = [i for i in attrs if i not in payload] | ||||
|         if ci is not None: | ||||
|             payload.update(self.get_attr_values(not_existed, ci.id)) | ||||
|   | ||||
							
								
								
									
										46
									
								
								cmdb-api/api/lib/common_setting/common_data.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										46
									
								
								cmdb-api/api/lib/common_setting/common_data.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| from flask import abort | ||||
|  | ||||
| from api.extensions import db | ||||
| from api.lib.common_setting.resp_format import ErrFormat | ||||
| from api.models.common_setting import CommonData | ||||
|  | ||||
|  | ||||
| class CommonDataCRUD(object): | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_data_by_type(data_type): | ||||
|         return CommonData.get_by(data_type=data_type) | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_data_by_id(_id, to_dict=True): | ||||
|         return CommonData.get_by(first=True, id=_id, to_dict=to_dict) | ||||
|  | ||||
|     @staticmethod | ||||
|     def create_new_data(data_type, **kwargs): | ||||
|         try: | ||||
|             return CommonData.create(data_type=data_type, **kwargs) | ||||
|         except Exception as e: | ||||
|             db.session.rollback() | ||||
|             abort(400, str(e)) | ||||
|  | ||||
|     @staticmethod | ||||
|     def update_data(_id, **kwargs): | ||||
|         existed = CommonDataCRUD.get_data_by_id(_id, to_dict=False) | ||||
|         if not existed: | ||||
|             abort(404, ErrFormat.common_data_not_found.format(_id)) | ||||
|         try: | ||||
|             return existed.update(**kwargs) | ||||
|         except Exception as e: | ||||
|             db.session.rollback() | ||||
|             abort(400, str(e)) | ||||
|  | ||||
|     @staticmethod | ||||
|     def delete(_id): | ||||
|         existed = CommonDataCRUD.get_data_by_id(_id, to_dict=False) | ||||
|         if not existed: | ||||
|             abort(404, ErrFormat.common_data_not_found.format(_id)) | ||||
|         try: | ||||
|             existed.soft_delete() | ||||
|         except Exception as e: | ||||
|             db.session.rollback() | ||||
|             abort(400, str(e)) | ||||
| @@ -54,3 +54,4 @@ class ErrFormat(CommonErrFormat): | ||||
|     email_is_required = "邮箱不能为空" | ||||
|     email_format_error = "邮箱格式错误" | ||||
|  | ||||
|     common_data_not_found = "ID {} 找不到记录" | ||||
|   | ||||
| @@ -4,8 +4,7 @@ from api.lib.common_setting.utils import get_cur_time_str | ||||
|  | ||||
|  | ||||
| def allowed_file(filename, allowed_extensions): | ||||
|     return '.' in filename and \ | ||||
|            filename.rsplit('.', 1)[1].lower() in allowed_extensions | ||||
|     return '.' in filename and filename.rsplit('.', 1)[1].lower() in allowed_extensions | ||||
|  | ||||
|  | ||||
| def generate_new_file_name(name): | ||||
| @@ -13,4 +12,5 @@ def generate_new_file_name(name): | ||||
|     prev_name = ''.join(name.split(f".{ext}")[:-1]) | ||||
|     uid = str(uuid.uuid4()) | ||||
|     cur_str = get_cur_time_str('_') | ||||
|  | ||||
|     return f"{prev_name}_{cur_str}_{uid}.{ext}" | ||||
|   | ||||
| @@ -55,8 +55,8 @@ def args_validate(model_cls, exclude_args=None): | ||||
|                     if exclude_args and arg in exclude_args: | ||||
|                         continue | ||||
|  | ||||
|                     if attr.type.python_type == str and attr.type.length and \ | ||||
|                             len(request.values[arg] or '') > attr.type.length: | ||||
|                     if attr.type.python_type == str and attr.type.length and ( | ||||
|                             len(request.values[arg] or '') > attr.type.length): | ||||
|  | ||||
|                         return abort(400, CommonErrFormat.argument_str_length_limit.format(arg, attr.type.length)) | ||||
|                     elif attr.type.python_type in (int, float) and request.values[arg]: | ||||
|   | ||||
| @@ -5,8 +5,10 @@ import hashlib | ||||
|  | ||||
| import requests | ||||
| import six | ||||
| from flask import abort, session | ||||
| from flask import current_app, request | ||||
| from flask import abort | ||||
| from flask import current_app | ||||
| from flask import request | ||||
| from flask import session | ||||
| from flask_login import current_user | ||||
|  | ||||
| from api.extensions import cache | ||||
| @@ -85,8 +87,8 @@ class ACLManager(object): | ||||
|         if user: | ||||
|             return Role.get_by(name=name, uid=user.uid, first=True, to_dict=False) | ||||
|  | ||||
|         return Role.get_by(name=name, app_id=self.app_id, first=True, to_dict=False) or \ | ||||
|                Role.get_by(name=name, first=True, to_dict=False) | ||||
|         return (Role.get_by(name=name, app_id=self.app_id, first=True, to_dict=False) or | ||||
|                 Role.get_by(name=name, first=True, to_dict=False)) | ||||
|  | ||||
|     def add_resource(self, name, resource_type_name=None): | ||||
|         resource_type = ResourceType.get_by(name=resource_type_name, first=True, to_dict=False) | ||||
|   | ||||
| @@ -8,7 +8,9 @@ from flask import abort | ||||
| from flask import current_app | ||||
|  | ||||
| from api.extensions import db | ||||
| from api.lib.perm.acl.audit import AuditCRUD, AuditOperateType, AuditScope | ||||
| from api.lib.perm.acl.audit import AuditCRUD | ||||
| from api.lib.perm.acl.audit import AuditOperateType | ||||
| from api.lib.perm.acl.audit import AuditScope | ||||
| from api.lib.perm.acl.resp_format import ErrFormat | ||||
| from api.models.acl import App | ||||
|  | ||||
|   | ||||
| @@ -9,8 +9,16 @@ from flask_login import current_user | ||||
| from sqlalchemy import func | ||||
|  | ||||
| from api.lib.perm.acl import AppCache | ||||
| from api.models.acl import AuditPermissionLog, AuditResourceLog, AuditRoleLog, AuditTriggerLog, Permission, Resource, \ | ||||
|     ResourceGroup, ResourceType, Role, RolePermission | ||||
| from api.models.acl import AuditPermissionLog | ||||
| from api.models.acl import AuditResourceLog | ||||
| from api.models.acl import AuditRoleLog | ||||
| from api.models.acl import AuditTriggerLog | ||||
| from api.models.acl import Permission | ||||
| from api.models.acl import Resource | ||||
| from api.models.acl import ResourceGroup | ||||
| from api.models.acl import ResourceType | ||||
| from api.models.acl import Role | ||||
| from api.models.acl import RolePermission | ||||
|  | ||||
|  | ||||
| class AuditScope(str, Enum): | ||||
| @@ -91,11 +99,8 @@ class AuditCRUD(object): | ||||
|                 criterion.append(AuditPermissionLog.operate_type == v) | ||||
|  | ||||
|         records = AuditPermissionLog.query.filter( | ||||
|             AuditPermissionLog.deleted == 0, | ||||
|             *criterion) \ | ||||
|             .order_by(AuditPermissionLog.id.desc()) \ | ||||
|             .offset((page - 1) * page_size) \ | ||||
|             .limit(page_size).all() | ||||
|             AuditPermissionLog.deleted == 0, *criterion).order_by( | ||||
|             AuditPermissionLog.id.desc()).offset((page - 1) * page_size).limit(page_size).all() | ||||
|  | ||||
|         data = { | ||||
|             'data': [r.to_dict() for r in records], | ||||
| @@ -158,10 +163,8 @@ class AuditCRUD(object): | ||||
|             elif k == 'operate_type': | ||||
|                 criterion.append(AuditRoleLog.operate_type == v) | ||||
|  | ||||
|         records = AuditRoleLog.query.filter(AuditRoleLog.deleted == 0, *criterion) \ | ||||
|             .order_by(AuditRoleLog.id.desc()) \ | ||||
|             .offset((page - 1) * page_size) \ | ||||
|             .limit(page_size).all() | ||||
|         records = AuditRoleLog.query.filter(AuditRoleLog.deleted == 0, *criterion).order_by( | ||||
|             AuditRoleLog.id.desc()).offset((page - 1) * page_size).limit(page_size).all() | ||||
|  | ||||
|         data = { | ||||
|             'data': [r.to_dict() for r in records], | ||||
| @@ -223,11 +226,8 @@ class AuditCRUD(object): | ||||
|                 criterion.append(AuditResourceLog.operate_type == v) | ||||
|  | ||||
|         records = AuditResourceLog.query.filter( | ||||
|             AuditResourceLog.deleted == 0, | ||||
|             *criterion) \ | ||||
|             .order_by(AuditResourceLog.id.desc()) \ | ||||
|             .offset((page - 1) * page_size) \ | ||||
|             .limit(page_size).all() | ||||
|             AuditResourceLog.deleted == 0, *criterion).order_by( | ||||
|             AuditResourceLog.id.desc()).offset((page - 1) * page_size).limit(page_size).all() | ||||
|  | ||||
|         data = { | ||||
|             'data': [r.to_dict() for r in records], | ||||
| @@ -257,11 +257,8 @@ class AuditCRUD(object): | ||||
|                 criterion.append(AuditTriggerLog.operate_type == v) | ||||
|  | ||||
|         records = AuditTriggerLog.query.filter( | ||||
|             AuditTriggerLog.deleted == 0, | ||||
|             *criterion) \ | ||||
|             .order_by(AuditTriggerLog.id.desc()) \ | ||||
|             .offset((page - 1) * page_size) \ | ||||
|             .limit(page_size).all() | ||||
|             AuditTriggerLog.deleted == 0, *criterion).order_by( | ||||
|             AuditTriggerLog.id.desc()).offset((page - 1) * page_size).limit(page_size).all() | ||||
|  | ||||
|         data = { | ||||
|             'data': [r.to_dict() for r in records], | ||||
|   | ||||
| @@ -60,15 +60,15 @@ class UserCache(object): | ||||
|  | ||||
|     @classmethod | ||||
|     def get(cls, key): | ||||
|         user = cache.get(cls.PREFIX_ID.format(key)) or \ | ||||
|                cache.get(cls.PREFIX_NAME.format(key)) or \ | ||||
|                cache.get(cls.PREFIX_NICK.format(key)) or \ | ||||
|                cache.get(cls.PREFIX_WXID.format(key)) | ||||
|         user = (cache.get(cls.PREFIX_ID.format(key)) or | ||||
|                 cache.get(cls.PREFIX_NAME.format(key)) or | ||||
|                 cache.get(cls.PREFIX_NICK.format(key)) or | ||||
|                 cache.get(cls.PREFIX_WXID.format(key))) | ||||
|         if not user: | ||||
|             user = User.query.get(key) or \ | ||||
|                    User.query.get_by_username(key) or \ | ||||
|                    User.query.get_by_nickname(key) or \ | ||||
|                    User.query.get_by_wxid(key) | ||||
|             user = (User.query.get(key) or | ||||
|                     User.query.get_by_username(key) or | ||||
|                     User.query.get_by_nickname(key) or | ||||
|                     User.query.get_by_wxid(key)) | ||||
|         if user: | ||||
|             cls.set(user) | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,9 @@ import datetime | ||||
| from flask import abort | ||||
|  | ||||
| from api.extensions import db | ||||
| from api.lib.perm.acl.audit import AuditCRUD, AuditOperateType, AuditOperateSource | ||||
| from api.lib.perm.acl.audit import AuditCRUD | ||||
| from api.lib.perm.acl.audit import AuditOperateSource | ||||
| from api.lib.perm.acl.audit import AuditOperateType | ||||
| from api.lib.perm.acl.cache import PermissionCache | ||||
| from api.lib.perm.acl.cache import RoleCache | ||||
| from api.lib.perm.acl.cache import UserCache | ||||
| @@ -97,8 +99,8 @@ class PermissionCRUD(object): | ||||
|         elif group_id is not None: | ||||
|             from api.models.acl import ResourceGroup | ||||
|  | ||||
|             group = ResourceGroup.get_by_id(group_id) or \ | ||||
|                     abort(404, ErrFormat.resource_group_not_found.format("id={}".format(group_id))) | ||||
|             group = ResourceGroup.get_by_id(group_id) or abort( | ||||
|                 404, ErrFormat.resource_group_not_found.format("id={}".format(group_id))) | ||||
|             app_id = group.app_id | ||||
|             rt_id = group.resource_type_id | ||||
|             if not perms: | ||||
| @@ -206,8 +208,8 @@ class PermissionCRUD(object): | ||||
|         if resource_id is not None: | ||||
|             from api.models.acl import Resource | ||||
|  | ||||
|             resource = Resource.get_by_id(resource_id) or \ | ||||
|                        abort(404, ErrFormat.resource_not_found.format("id={}".format(resource_id))) | ||||
|             resource = Resource.get_by_id(resource_id) or abort( | ||||
|                 404, ErrFormat.resource_not_found.format("id={}".format(resource_id))) | ||||
|             app_id = resource.app_id | ||||
|             rt_id = resource.resource_type_id | ||||
|             if not perms: | ||||
| @@ -216,8 +218,8 @@ class PermissionCRUD(object): | ||||
|         elif group_id is not None: | ||||
|             from api.models.acl import ResourceGroup | ||||
|  | ||||
|             group = ResourceGroup.get_by_id(group_id) or \ | ||||
|                     abort(404, ErrFormat.resource_group_not_found.format("id={}".format(group_id))) | ||||
|             group = ResourceGroup.get_by_id(group_id) or abort( | ||||
|                 404, ErrFormat.resource_group_not_found.format("id={}".format(group_id))) | ||||
|             app_id = group.app_id | ||||
|  | ||||
|             rt_id = group.resource_type_id | ||||
|   | ||||
| @@ -5,7 +5,9 @@ from flask import abort | ||||
| from flask import current_app | ||||
|  | ||||
| from api.extensions import db | ||||
| from api.lib.perm.acl.audit import AuditCRUD, AuditOperateType, AuditScope | ||||
| from api.lib.perm.acl.audit import AuditCRUD | ||||
| from api.lib.perm.acl.audit import AuditOperateType | ||||
| from api.lib.perm.acl.audit import AuditScope | ||||
| from api.lib.perm.acl.cache import ResourceCache | ||||
| from api.lib.perm.acl.cache import ResourceGroupCache | ||||
| from api.lib.perm.acl.cache import UserCache | ||||
| @@ -102,8 +104,8 @@ class ResourceTypeCRUD(object): | ||||
|  | ||||
|     @classmethod | ||||
|     def delete(cls, rt_id): | ||||
|         rt = ResourceType.get_by_id(rt_id) or \ | ||||
|              abort(404, ErrFormat.resource_type_not_found.format("id={}".format(rt_id))) | ||||
|         rt = ResourceType.get_by_id(rt_id) or abort( | ||||
|             404, ErrFormat.resource_type_not_found.format("id={}".format(rt_id))) | ||||
|  | ||||
|         Resource.get_by(resource_type_id=rt_id) and abort(400, ErrFormat.resource_type_cannot_delete) | ||||
|  | ||||
| @@ -165,8 +167,8 @@ class ResourceGroupCRUD(object): | ||||
|  | ||||
|     @staticmethod | ||||
|     def add(name, type_id, app_id, uid=None): | ||||
|         ResourceGroup.get_by(name=name, resource_type_id=type_id, app_id=app_id) and \ | ||||
|         abort(400, ErrFormat.resource_group_exists.format(name)) | ||||
|         ResourceGroup.get_by(name=name, resource_type_id=type_id, app_id=app_id) and abort( | ||||
|             400, ErrFormat.resource_group_exists.format(name)) | ||||
|         rg = ResourceGroup.create(name=name, resource_type_id=type_id, app_id=app_id, uid=uid) | ||||
|  | ||||
|         AuditCRUD.add_resource_log(app_id, AuditOperateType.create, | ||||
| @@ -175,8 +177,8 @@ class ResourceGroupCRUD(object): | ||||
|  | ||||
|     @staticmethod | ||||
|     def update(rg_id, items): | ||||
|         rg = ResourceGroup.get_by_id(rg_id) or \ | ||||
|              abort(404, ErrFormat.resource_group_not_found.format("id={}".format(rg_id))) | ||||
|         rg = ResourceGroup.get_by_id(rg_id) or abort( | ||||
|             404, ErrFormat.resource_group_not_found.format("id={}".format(rg_id))) | ||||
|  | ||||
|         existed = ResourceGroupItems.get_by(group_id=rg_id, to_dict=False) | ||||
|         existed_ids = [i.resource_id for i in existed] | ||||
| @@ -196,8 +198,8 @@ class ResourceGroupCRUD(object): | ||||
|  | ||||
|     @staticmethod | ||||
|     def delete(rg_id): | ||||
|         rg = ResourceGroup.get_by_id(rg_id) or \ | ||||
|              abort(404, ErrFormat.resource_group_not_found.format("id={}".format(rg_id))) | ||||
|         rg = ResourceGroup.get_by_id(rg_id) or abort( | ||||
|             404, ErrFormat.resource_group_not_found.format("id={}".format(rg_id))) | ||||
|  | ||||
|         origin = rg.to_dict() | ||||
|         rg.soft_delete() | ||||
| @@ -266,8 +268,8 @@ class ResourceCRUD(object): | ||||
|     def add(cls, name, type_id, app_id, uid=None): | ||||
|         type_id = cls._parse_resource_type_id(type_id, app_id) | ||||
|  | ||||
|         Resource.get_by(name=name, resource_type_id=type_id, app_id=app_id) and \ | ||||
|         abort(400, ErrFormat.resource_exists.format(name)) | ||||
|         Resource.get_by(name=name, resource_type_id=type_id, app_id=app_id) and abort( | ||||
|             400, ErrFormat.resource_exists.format(name)) | ||||
|  | ||||
|         r = Resource.create(name=name, resource_type_id=type_id, app_id=app_id, uid=uid) | ||||
|  | ||||
|   | ||||
| @@ -10,7 +10,9 @@ from sqlalchemy import or_ | ||||
|  | ||||
| from api.extensions import db | ||||
| from api.lib.perm.acl.app import AppCRUD | ||||
| from api.lib.perm.acl.audit import AuditCRUD, AuditOperateType, AuditScope | ||||
| from api.lib.perm.acl.audit import AuditCRUD | ||||
| from api.lib.perm.acl.audit import AuditOperateType | ||||
| from api.lib.perm.acl.audit import AuditScope | ||||
| from api.lib.perm.acl.cache import AppCache | ||||
| from api.lib.perm.acl.cache import HasResourceRoleCache | ||||
| from api.lib.perm.acl.cache import RoleCache | ||||
| @@ -69,16 +71,16 @@ class RoleRelationCRUD(object): | ||||
|     @staticmethod | ||||
|     def get_parent_ids(rid, app_id): | ||||
|         if app_id is not None: | ||||
|             return [i.parent_id for i in RoleRelation.get_by(child_id=rid, app_id=app_id, to_dict=False)] + \ | ||||
|                    [i.parent_id for i in RoleRelation.get_by(child_id=rid, app_id=None, to_dict=False)] | ||||
|             return ([i.parent_id for i in RoleRelation.get_by(child_id=rid, app_id=app_id, to_dict=False)] + | ||||
|                     [i.parent_id for i in RoleRelation.get_by(child_id=rid, app_id=None, to_dict=False)]) | ||||
|         else: | ||||
|             return [i.parent_id for i in RoleRelation.get_by(child_id=rid, app_id=app_id, to_dict=False)] | ||||
|  | ||||
|     @staticmethod | ||||
|     def get_child_ids(rid, app_id): | ||||
|         if app_id is not None: | ||||
|             return [i.child_id for i in RoleRelation.get_by(parent_id=rid, app_id=app_id, to_dict=False)] + \ | ||||
|                    [i.child_id for i in RoleRelation.get_by(parent_id=rid, app_id=None, to_dict=False)] | ||||
|             return ([i.child_id for i in RoleRelation.get_by(parent_id=rid, app_id=app_id, to_dict=False)] + | ||||
|                     [i.child_id for i in RoleRelation.get_by(parent_id=rid, app_id=None, to_dict=False)]) | ||||
|         else: | ||||
|             return [i.child_id for i in RoleRelation.get_by(parent_id=rid, app_id=app_id, to_dict=False)] | ||||
|  | ||||
|   | ||||
| @@ -6,9 +6,10 @@ import json | ||||
| import re | ||||
| from fnmatch import fnmatch | ||||
|  | ||||
| from flask import abort, current_app | ||||
| from flask import abort | ||||
|  | ||||
| from api.lib.perm.acl.audit import AuditCRUD, AuditOperateType | ||||
| from api.lib.perm.acl.audit import AuditCRUD | ||||
| from api.lib.perm.acl.audit import AuditOperateType | ||||
| from api.lib.perm.acl.cache import UserCache | ||||
| from api.lib.perm.acl.const import ACL_QUEUE | ||||
| from api.lib.perm.acl.resp_format import ErrFormat | ||||
|   | ||||
| @@ -9,7 +9,9 @@ from flask import abort | ||||
| from flask_login import current_user | ||||
|  | ||||
| from api.extensions import db | ||||
| from api.lib.perm.acl.audit import AuditCRUD, AuditOperateType, AuditScope | ||||
| from api.lib.perm.acl.audit import AuditCRUD | ||||
| from api.lib.perm.acl.audit import AuditOperateType | ||||
| from api.lib.perm.acl.audit import AuditScope | ||||
| from api.lib.perm.acl.cache import UserCache | ||||
| from api.lib.perm.acl.resp_format import ErrFormat | ||||
| from api.lib.perm.acl.role import RoleCRUD | ||||
| @@ -49,11 +51,9 @@ class UserCRUD(object): | ||||
|         kwargs['block'] = 0 | ||||
|         kwargs['key'], kwargs['secret'] = cls.gen_key_secret() | ||||
|  | ||||
|         user_employee = db.session.query(User).filter(User.deleted.is_(False)).order_by( | ||||
|             User.employee_id.desc()).first() | ||||
|         user_employee = db.session.query(User).filter(User.deleted.is_(False)).order_by(User.employee_id.desc()).first() | ||||
|  | ||||
|         biggest_employee_id = int(float(user_employee.employee_id)) \ | ||||
|             if user_employee is not None else 0 | ||||
|         biggest_employee_id = int(float(user_employee.employee_id)) if user_employee is not None else 0 | ||||
|  | ||||
|         kwargs['employee_id'] = '{0:04d}'.format(biggest_employee_id + 1) | ||||
|         user = User.create(**kwargs) | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| # -*- coding:utf-8 -*-  | ||||
|  | ||||
| import base64 | ||||
| import json | ||||
| import sys | ||||
| import time | ||||
| from typing import Set | ||||
| @@ -113,7 +112,7 @@ class RedisHandler(object): | ||||
|         try: | ||||
|             ret = self.r.hdel(prefix, key_id) | ||||
|             if not ret: | ||||
|                 current_app.logger.warn("[{0}] is not in redis".format(key_id)) | ||||
|                 current_app.logger.warning("[{0}] is not in redis".format(key_id)) | ||||
|         except Exception as e: | ||||
|             current_app.logger.error("delete redis key error, {0}".format(str(e))) | ||||
|  | ||||
| @@ -204,9 +203,9 @@ class ESHandler(object): | ||||
|  | ||||
|         res = self.es.search(index=self.index, body=query, filter_path=filter_path) | ||||
|         if res['hits'].get('hits'): | ||||
|             return res['hits']['total']['value'], \ | ||||
|                    [i['_source'] for i in res['hits']['hits']], \ | ||||
|                    res.get("aggregations", {}) | ||||
|             return (res['hits']['total']['value'], | ||||
|                     [i['_source'] for i in res['hits']['hits']], | ||||
|                     res.get("aggregations", {})) | ||||
|         else: | ||||
|             return 0, [], {} | ||||
|  | ||||
| @@ -257,93 +256,10 @@ class Lock(object): | ||||
|             self.release() | ||||
|  | ||||
|  | ||||
| class Redis2Handler(object): | ||||
|     def __init__(self, flask_app=None, prefix=None): | ||||
|         self.flask_app = flask_app | ||||
|         self.prefix = prefix | ||||
|         self.r = None | ||||
|  | ||||
|     def init_app(self, app): | ||||
|         self.flask_app = app | ||||
|         config = self.flask_app.config | ||||
|         try: | ||||
|             pool = redis.ConnectionPool( | ||||
|                 max_connections=config.get("REDIS_MAX_CONN"), | ||||
|                 host=config.get("ONEAGENT_REDIS_HOST"), | ||||
|                 port=config.get("ONEAGENT_REDIS_PORT"), | ||||
|                 db=config.get("ONEAGENT_REDIS_DB"), | ||||
|                 password=config.get("ONEAGENT_REDIS_PASSWORD") | ||||
|             ) | ||||
|             self.r = redis.Redis(connection_pool=pool) | ||||
|         except Exception as e: | ||||
|             current_app.logger.warning(str(e)) | ||||
|             current_app.logger.error("init redis connection failed") | ||||
|  | ||||
|     def get(self, key): | ||||
|         try: | ||||
|             value = json.loads(self.r.get(key)) | ||||
|         except: | ||||
|             return | ||||
|  | ||||
|         return value | ||||
|  | ||||
|     def lrange(self, key, start=0, end=-1): | ||||
|         try: | ||||
|             value = "".join(map(redis_decode, self.r.lrange(key, start, end) or [])) | ||||
|         except: | ||||
|             return | ||||
|  | ||||
|         return value | ||||
|  | ||||
|     def lrange2(self, key, start=0, end=-1): | ||||
|         try: | ||||
|             return list(map(redis_decode, self.r.lrange(key, start, end) or [])) | ||||
|         except: | ||||
|             return [] | ||||
|  | ||||
|     def llen(self, key): | ||||
|         try: | ||||
|             return self.r.llen(key) or 0 | ||||
|         except: | ||||
|             return 0 | ||||
|  | ||||
|     def hget(self, key, field): | ||||
|         try: | ||||
|             return self.r.hget(key, field) | ||||
|         except Exception as e: | ||||
|             current_app.logger.warning("hget redis failed, %s" % str(e)) | ||||
|             return | ||||
|  | ||||
|     def hset(self, key, field, value): | ||||
|         try: | ||||
|             self.r.hset(key, field, value) | ||||
|         except Exception as e: | ||||
|             current_app.logger.warning("hset redis failed, %s" % str(e)) | ||||
|             return | ||||
|  | ||||
|     def expire(self, key, timeout): | ||||
|         try: | ||||
|             self.r.expire(key, timeout) | ||||
|         except Exception as e: | ||||
|             current_app.logger.warning("expire redis failed, %s" % str(e)) | ||||
|             return | ||||
|  | ||||
|  | ||||
| def redis_decode(x): | ||||
|     try: | ||||
|         return x.decode() | ||||
|     except Exception as e: | ||||
|         print(x, e) | ||||
|         try: | ||||
|             return x.decode("gb18030") | ||||
|         except: | ||||
|             return "decode failed" | ||||
|  | ||||
|  | ||||
| class AESCrypto(object): | ||||
|     BLOCK_SIZE = 16  # Bytes | ||||
|     pad = lambda s: s + (AESCrypto.BLOCK_SIZE - len(s) % AESCrypto.BLOCK_SIZE) * \ | ||||
|                     chr(AESCrypto.BLOCK_SIZE - len(s) % AESCrypto.BLOCK_SIZE) | ||||
|     pad = lambda s: s + ((AESCrypto.BLOCK_SIZE - len(s) % AESCrypto.BLOCK_SIZE) * | ||||
|                          chr(AESCrypto.BLOCK_SIZE - len(s) % AESCrypto.BLOCK_SIZE)) | ||||
|     unpad = lambda s: s[:-ord(s[len(s) - 1:])] | ||||
|  | ||||
|     iv = '0102030405060708' | ||||
| @@ -352,7 +268,7 @@ class AESCrypto(object): | ||||
|     def key(): | ||||
|         key = current_app.config.get("SECRET_KEY")[:16] | ||||
|         if len(key) < 16: | ||||
|             key = "{}{}".format(key, (16 - len(key) * "x")) | ||||
|             key = "{}{}".format(key, (16 - len(key)) * "x") | ||||
|  | ||||
|         return key.encode('utf8') | ||||
|  | ||||
|   | ||||
| @@ -80,3 +80,10 @@ class InternalMessage(Model): | ||||
|     category = db.Column(db.VARCHAR(128), nullable=False) | ||||
|     message_data = db.Column(db.JSON, nullable=True) | ||||
|     employee_id = db.Column(db.Integer, db.ForeignKey('common_employee.employee_id'), comment='ID') | ||||
|  | ||||
|  | ||||
| class CommonData(Model): | ||||
|     __table_name__ = 'common_data' | ||||
|  | ||||
|     data_type = db.Column(db.VARCHAR(255), default='') | ||||
|     data = db.Column(db.JSON) | ||||
|   | ||||
| @@ -2,7 +2,8 @@ | ||||
|  | ||||
| import os | ||||
| import sys | ||||
| from inspect import getmembers, isclass | ||||
| from inspect import getmembers | ||||
| from inspect import isclass | ||||
|  | ||||
| import six | ||||
| from flask import jsonify | ||||
|   | ||||
| @@ -5,17 +5,20 @@ import re | ||||
|  | ||||
| from celery_once import QueueOnce | ||||
| from flask import current_app | ||||
| from werkzeug.exceptions import BadRequest, NotFound | ||||
| from werkzeug.exceptions import BadRequest | ||||
| from werkzeug.exceptions import NotFound | ||||
|  | ||||
| from api.extensions import celery | ||||
| from api.extensions import db | ||||
| from api.lib.perm.acl.audit import AuditCRUD | ||||
| from api.lib.perm.acl.audit import AuditOperateSource | ||||
| from api.lib.perm.acl.audit import AuditOperateType | ||||
| from api.lib.perm.acl.cache import AppCache | ||||
| from api.lib.perm.acl.cache import RoleCache | ||||
| from api.lib.perm.acl.cache import RoleRelationCache | ||||
| from api.lib.perm.acl.cache import UserCache | ||||
| from api.lib.perm.acl.const import ACL_QUEUE | ||||
| from api.lib.perm.acl.record import OperateRecordCRUD | ||||
| from api.lib.perm.acl.audit import AuditCRUD, AuditOperateType, AuditOperateSource | ||||
| from api.models.acl import Resource | ||||
| from api.models.acl import Role | ||||
| from api.models.acl import Trigger | ||||
|   | ||||
| @@ -2,12 +2,13 @@ | ||||
|  | ||||
| import datetime | ||||
|  | ||||
| import six | ||||
| import jwt | ||||
| import six | ||||
| from flask import abort | ||||
| from flask import current_app | ||||
| from flask import request | ||||
| from flask_login import login_user, logout_user | ||||
| from flask_login import login_user | ||||
| from flask_login import logout_user | ||||
|  | ||||
| from api.lib.decorator import args_required | ||||
| from api.lib.perm.acl.cache import User | ||||
|   | ||||
| @@ -11,7 +11,8 @@ from api.lib.cmdb.cache import CITypeCache | ||||
| from api.lib.cmdb.ci import CIManager | ||||
| from api.lib.cmdb.ci import CIRelationManager | ||||
| from api.lib.cmdb.const import ExistPolicy | ||||
| from api.lib.cmdb.const import ResourceTypeEnum, PermEnum | ||||
| from api.lib.cmdb.const import PermEnum | ||||
| from api.lib.cmdb.const import ResourceTypeEnum | ||||
| from api.lib.cmdb.const import RetKey | ||||
| from api.lib.cmdb.perms import has_perm_for_ci | ||||
| from api.lib.cmdb.search import SearchError | ||||
|   | ||||
| @@ -6,7 +6,9 @@ from flask import request | ||||
|  | ||||
| from api.lib.cmdb.ci_type import CITypeManager | ||||
| from api.lib.cmdb.ci_type import CITypeRelationManager | ||||
| from api.lib.cmdb.const import PermEnum, ResourceTypeEnum, RoleEnum | ||||
| from api.lib.cmdb.const import PermEnum | ||||
| from api.lib.cmdb.const import ResourceTypeEnum | ||||
| from api.lib.cmdb.const import RoleEnum | ||||
| from api.lib.cmdb.resp_format import ErrFormat | ||||
| from api.lib.decorator import args_required | ||||
| from api.lib.perm.acl.acl import ACLManager | ||||
|   | ||||
| @@ -7,7 +7,8 @@ from flask import abort | ||||
| from flask import request | ||||
|  | ||||
| from api.lib.cmdb.ci import CIManager | ||||
| from api.lib.cmdb.const import ResourceTypeEnum, PermEnum | ||||
| from api.lib.cmdb.const import PermEnum | ||||
| from api.lib.cmdb.const import ResourceTypeEnum | ||||
| from api.lib.cmdb.const import RoleEnum | ||||
| from api.lib.cmdb.history import AttributeHistoryManger | ||||
| from api.lib.cmdb.history import CITypeHistoryManager | ||||
|   | ||||
| @@ -5,7 +5,9 @@ from flask import abort | ||||
| from flask import request | ||||
|  | ||||
| from api.lib.cmdb.ci_type import CITypeManager | ||||
| from api.lib.cmdb.const import PermEnum, ResourceTypeEnum, RoleEnum | ||||
| from api.lib.cmdb.const import PermEnum | ||||
| from api.lib.cmdb.const import ResourceTypeEnum | ||||
| from api.lib.cmdb.const import RoleEnum | ||||
| from api.lib.cmdb.perms import CIFilterPermsCRUD | ||||
| from api.lib.cmdb.preference import PreferenceManager | ||||
| from api.lib.cmdb.resp_format import ErrFormat | ||||
|   | ||||
							
								
								
									
										35
									
								
								cmdb-api/api/views/common_setting/common_data.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										35
									
								
								cmdb-api/api/views/common_setting/common_data.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| from flask import request | ||||
|  | ||||
| from api.lib.common_setting.common_data import CommonDataCRUD | ||||
| from api.resource import APIView | ||||
|  | ||||
| prefix = '/data' | ||||
|  | ||||
|  | ||||
| class DataView(APIView): | ||||
|     url_prefix = (f'{prefix}/<string:data_type>',) | ||||
|  | ||||
|     def get(self, data_type): | ||||
|         data_list = CommonDataCRUD.get_data_by_type(data_type) | ||||
|  | ||||
|         return self.jsonify(data_list) | ||||
|  | ||||
|     def post(self, data_type): | ||||
|         params = request.json | ||||
|         CommonDataCRUD.create_new_data(data_type, **params) | ||||
|  | ||||
|         return self.jsonify(params) | ||||
|  | ||||
|  | ||||
| class DataViewWithId(APIView): | ||||
|     url_prefix = (f'{prefix}/<string:data_type>/<int:_id>',) | ||||
|  | ||||
|     def put(self, data_type, _id): | ||||
|         params = request.json | ||||
|         res = CommonDataCRUD.update_data(_id, **params) | ||||
|  | ||||
|         return self.jsonify(res.to_dict()) | ||||
|  | ||||
|     def delete(self, data_type, _id): | ||||
|         CommonDataCRUD.delete(_id) | ||||
|         return self.jsonify({}) | ||||
| @@ -6,7 +6,9 @@ from flask import Blueprint | ||||
| from flask_restful import Api | ||||
|  | ||||
| from api.resource import register_resources | ||||
| from .account import LoginView, LogoutView, AuthWithKeyView | ||||
| from .account import AuthWithKeyView | ||||
| from .account import LoginView | ||||
| from .account import LogoutView | ||||
|  | ||||
| HERE = os.path.abspath(os.path.dirname(__file__)) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user