mirror of
				https://github.com/veops/cmdb.git
				synced 2025-10-31 19:39:24 +08:00 
			
		
		
		
	/ci_types/<int:type_id>/attributes/transfer and /ci_types/<int:type_id>/attribute_groups/transfer
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -38,6 +38,7 @@ pip-log.txt | ||||
| .tox | ||||
| nosetests.xml | ||||
| .pytest_cache | ||||
| cmdb-api/test-output | ||||
|  | ||||
| # Translations | ||||
| *.mo | ||||
|   | ||||
| @@ -23,6 +23,7 @@ from api.models.cmdb import CITypeGroupItem | ||||
| from api.models.cmdb import CITypeRelation | ||||
| from api.models.cmdb import PreferenceShowAttributes | ||||
| from api.models.cmdb import PreferenceTreeView | ||||
| from api.tasks.cmdb import ci_type_attribute_order_rebuild | ||||
|  | ||||
|  | ||||
| class CITypeManager(object): | ||||
| @@ -55,16 +56,32 @@ class CITypeManager(object): | ||||
|         ci_type = CITypeCache.get(_type) or abort(404, "CIType <{0}> is not found".format(_type)) | ||||
|         return ci_type.to_dict() | ||||
|  | ||||
|     @staticmethod | ||||
|     def _validate_unique(type_id=None, name=None, alias=None): | ||||
|         if name is not None: | ||||
|             ci_type = CIType.get_by(name=name, first=True, to_dict=False) | ||||
|         elif alias is not None: | ||||
|             ci_type = CIType.get_by(alias=alias, first=True, to_dict=False) | ||||
|         else: | ||||
|             return | ||||
|  | ||||
|         if type_id is not None and ci_type.id != type_id: | ||||
|             return abort(400, "CIType <{0}> is already existed".format(name or alias)) | ||||
|  | ||||
|         if type_id is None and ci_type is not None: | ||||
|             return abort(400, "CIType <{0}> is already existed".format(name or alias)) | ||||
|  | ||||
|     @classmethod | ||||
|     @kwargs_required("name") | ||||
|     def add(cls, **kwargs): | ||||
|         unique_key = kwargs.pop("unique_key", None) | ||||
|         unique_key = AttributeCache.get(unique_key) or abort(404, "Unique key is not defined") | ||||
|  | ||||
|         CIType.get_by(name=kwargs['name']) and abort(404, "CIType <{0}> is already existed".format(kwargs.get("name"))) | ||||
|  | ||||
|         kwargs["alias"] = kwargs["name"] if not kwargs.get("alias") else kwargs["alias"] | ||||
|  | ||||
|         cls._validate_unique(name=kwargs['name']) | ||||
|         cls._validate_unique(alias=kwargs['alias']) | ||||
|  | ||||
|         kwargs["unique_id"] = unique_key.id | ||||
|         ci_type = CIType.create(**kwargs) | ||||
|  | ||||
| @@ -88,6 +105,9 @@ class CITypeManager(object): | ||||
|  | ||||
|         ci_type = cls.check_is_existed(type_id) | ||||
|  | ||||
|         cls._validate_unique(type_id=type_id, name=kwargs.get('name')) | ||||
|         cls._validate_unique(type_id=type_id, alias=kwargs.get('alias')) | ||||
|  | ||||
|         unique_key = kwargs.pop("unique_key", None) | ||||
|         unique_key = AttributeCache.get(unique_key) | ||||
|         if unique_key is not None: | ||||
| @@ -305,6 +325,31 @@ class CITypeAttributeManager(object): | ||||
|  | ||||
|         CITypeAttributesCache.clean(type_id) | ||||
|  | ||||
|     @classmethod | ||||
|     def transfer(cls, type_id, _from, _to): | ||||
|         current_app.logger.info("[{0}] {1} -> {2}".format(type_id, _from, _to)) | ||||
|         attr_id = _from.get('attr_id') | ||||
|         from_group_id = _from.get('group_id') | ||||
|         to_group_id = _to.get('group_id') | ||||
|         order = _to.get('order') | ||||
|  | ||||
|         if from_group_id != to_group_id: | ||||
|             if from_group_id is not None: | ||||
|                 CITypeAttributeGroupManager.delete_item(from_group_id, attr_id) | ||||
|  | ||||
|             if to_group_id is not None: | ||||
|                 CITypeAttributeGroupManager.add_item(to_group_id, attr_id, order) | ||||
|  | ||||
|         elif from_group_id: | ||||
|             CITypeAttributeGroupManager.update_item(from_group_id, attr_id, order) | ||||
|  | ||||
|         else:  # other attribute transfer | ||||
|             return abort(400, "invalid operation!!!") | ||||
|  | ||||
|         CITypeAttributesCache.clean(type_id) | ||||
|  | ||||
|         ci_type_attribute_order_rebuild.apply_async(args=(type_id,), queue=CMDB_QUEUE) | ||||
|  | ||||
|  | ||||
| class CITypeRelationManager(object): | ||||
|     """ | ||||
| @@ -455,3 +500,86 @@ class CITypeAttributeGroupManager(object): | ||||
|             item.soft_delete() | ||||
|  | ||||
|         return group_id | ||||
|  | ||||
|     @classmethod | ||||
|     def add_item(cls, group_id, attr_id, order): | ||||
|         db.session.remove() | ||||
|  | ||||
|         existed = CITypeAttributeGroupItem.get_by(group_id=group_id, | ||||
|                                                   attr_id=attr_id, | ||||
|                                                   first=True, | ||||
|                                                   to_dict=False) | ||||
|         if existed is not None: | ||||
|             existed.update(order=order) | ||||
|         else: | ||||
|             CITypeAttributeGroupItem.create(group_id=group_id, attr_id=attr_id, order=order) | ||||
|  | ||||
|         gt_items = db.session.query(CITypeAttributeGroupItem).filter( | ||||
|             CITypeAttributeGroupItem.deleted.is_(False)).filter(CITypeAttributeGroupItem.order > order) | ||||
|         for _item in gt_items: | ||||
|             _order = _item.order | ||||
|             _item.update(order=_order + 1) | ||||
|  | ||||
|     @classmethod | ||||
|     def update_item(cls, group_id, attr_id, order): | ||||
|         db.session.remove() | ||||
|  | ||||
|         existed = CITypeAttributeGroupItem.get_by(group_id=group_id, | ||||
|                                                   attr_id=attr_id, | ||||
|                                                   first=True, | ||||
|                                                   to_dict=False) | ||||
|         existed or abort(404, "Group<{0}> - Attribute<{1}> is not found".format(group_id, attr_id)) | ||||
|  | ||||
|         if existed.order > order:  # forward, +1 | ||||
|             items = db.session.query(CITypeAttributeGroupItem).filter( | ||||
|                 CITypeAttributeGroupItem.deleted.is_(False)).filter( | ||||
|                 CITypeAttributeGroupItem.order >= order).filter( | ||||
|                 CITypeAttributeGroupItem.order < existed.order) | ||||
|             for item in items: | ||||
|                 item.update(order=item.order + 1) | ||||
|  | ||||
|         elif existed.order < order:  # backward, -1 | ||||
|             items = db.session.query(CITypeAttributeGroupItem).filter( | ||||
|                 CITypeAttributeGroupItem.deleted.is_(False)).filter( | ||||
|                 CITypeAttributeGroupItem.order > existed.order).filter( | ||||
|                 CITypeAttributeGroupItem.order <= order) | ||||
|             for item in items: | ||||
|                 item.update(order=item.order - 1) | ||||
|  | ||||
|         existed.update(order=order) | ||||
|  | ||||
|     @classmethod | ||||
|     def delete_item(cls, group_id, attr_id): | ||||
|         db.session.remove() | ||||
|  | ||||
|         item = CITypeAttributeGroupItem.get_by(group_id=group_id, | ||||
|                                                attr_id=attr_id, | ||||
|                                                first=True, | ||||
|                                                to_dict=False) | ||||
|  | ||||
|         if item is not None: | ||||
|             item.soft_delete() | ||||
|             order = item.order | ||||
|             gt_items = db.session.query(CITypeAttributeGroupItem).filter( | ||||
|                 CITypeAttributeGroupItem.deleted.is_(False)).filter(CITypeAttributeGroupItem.order > order) | ||||
|             for _item in gt_items: | ||||
|                 _order = _item.order | ||||
|                 _item.update(order=_order - 1) | ||||
|  | ||||
|     @classmethod | ||||
|     def transfer(cls, type_id, _from, _to): | ||||
|         current_app.logger.info("CIType[{0}] {1} -> {2}".format(type_id, _from, _to)) | ||||
|         from_group = CITypeAttributeGroup.get_by_id(_from) | ||||
|         from_group or abort(404, "Group <{0}> is not found".format(_from)) | ||||
|  | ||||
|         to_group = CITypeAttributeGroup.get_by_id(_to) | ||||
|         to_group or abort(404, "Group <{0}> is not found".format(_to)) | ||||
|  | ||||
|         from_order, to_order = from_group.order, to_group.order | ||||
|  | ||||
|         from_group.update(order=to_order) | ||||
|         to_group.update(order=from_order) | ||||
|  | ||||
|         CITypeAttributesCache.clean(type_id) | ||||
|  | ||||
|         ci_type_attribute_order_rebuild.apply_async(args=(type_id,), queue=CMDB_QUEUE) | ||||
|   | ||||
| @@ -11,6 +11,7 @@ from api.extensions import celery | ||||
| from api.extensions import db | ||||
| from api.extensions import es | ||||
| from api.extensions import rd | ||||
| from api.lib.cmdb.cache import CITypeAttributeCache | ||||
| from api.lib.cmdb.const import CMDB_QUEUE | ||||
| from api.lib.cmdb.const import REDIS_PREFIX_CI | ||||
| from api.lib.cmdb.const import REDIS_PREFIX_CI_RELATION | ||||
| @@ -71,3 +72,23 @@ def ci_relation_delete(parent_id, child_id): | ||||
|     rd.create_or_update({parent_id: json.dumps(children)}, REDIS_PREFIX_CI_RELATION) | ||||
|  | ||||
|     current_app.logger.info("DELETE ci relation cache: {0} -> {1}".format(parent_id, child_id)) | ||||
|  | ||||
|  | ||||
| @celery.task(name="cmdb.ci_type_attribute_order_rebuild", queue=CMDB_QUEUE) | ||||
| def ci_type_attribute_order_rebuild(type_id): | ||||
|     current_app.logger.info('rebuild attribute order') | ||||
|     db.session.remove() | ||||
|  | ||||
|     from api.lib.cmdb.ci_type import CITypeAttributeGroupManager | ||||
|  | ||||
|     attrs = CITypeAttributeCache.get(type_id) | ||||
|     id2attr = {attr.attr_id: attr for attr in attrs} | ||||
|  | ||||
|     res = CITypeAttributeGroupManager.get_by_type_id(type_id, True) | ||||
|     order = 0 | ||||
|     for group in res: | ||||
|         for _attr in group.get('attributes'): | ||||
|             if order != id2attr.get(_attr['id']) and id2attr.get(_attr['id']): | ||||
|                 id2attr.get(_attr['id']).update(order=order) | ||||
|  | ||||
|             order += 1 | ||||
|   | ||||
| @@ -164,6 +164,34 @@ class CITypeAttributeView(APIView): | ||||
|         return self.jsonify(attributes=attr_id_list) | ||||
|  | ||||
|  | ||||
| class CITypeAttributeTransferView(APIView): | ||||
|     url_prefix = "/ci_types/<int:type_id>/attributes/transfer" | ||||
|  | ||||
|     @args_required('from') | ||||
|     @args_required('to') | ||||
|     def post(self, type_id): | ||||
|         _from = request.values.get('from')  # {'attr_id': xx, 'group_id': xx} | ||||
|         _to = request.values.get('to')  # {'group_id': xx, 'order': xxx} | ||||
|  | ||||
|         CITypeAttributeManager.transfer(type_id, _from, _to) | ||||
|  | ||||
|         return self.jsonify(code=200) | ||||
|  | ||||
|  | ||||
| class CITypeAttributeGroupTransferView(APIView): | ||||
|     url_prefix = "/ci_types/<int:type_id>/attribute_groups/transfer" | ||||
|  | ||||
|     @args_required('from') | ||||
|     @args_required('to') | ||||
|     def post(self, type_id): | ||||
|         _from = request.values.get('from')  # group_id | ||||
|         _to = request.values.get('to')  # group_id | ||||
|  | ||||
|         CITypeAttributeGroupManager.transfer(type_id, _from, _to) | ||||
|  | ||||
|         return self.jsonify(code=200) | ||||
|  | ||||
|  | ||||
| class CITypeAttributeGroupView(APIView): | ||||
|     url_prefix = ("/ci_types/<int:type_id>/attribute_groups", | ||||
|                   "/ci_types/attribute_groups/<int:group_id>") | ||||
|   | ||||
		Reference in New Issue
	
	Block a user