Exemple #1
0
    def create_or_update_attr_value(self,
                                    key,
                                    value,
                                    ci,
                                    _no_attribute_policy=ExistPolicy.IGNORE):
        """
        add or update attribute value, then write history
        :param key: id, name or alias
        :param value:
        :param ci: instance object
        :param _no_attribute_policy: ignore or reject
        :return:
        """
        attr = self._get_attr(key)
        if attr is None:
            if _no_attribute_policy == ExistPolicy.IGNORE:
                return
            if _no_attribute_policy == ExistPolicy.REJECT:
                return abort(400, 'attribute {0} does not exist'.format(key))

        value_table = TableMap(attr_name=attr.name).table

        if attr.is_list:
            value_list = [
                self._validate(attr, i, value_table, ci)
                for i in handle_arg_list(value)
            ]
            if not value_list:
                self.__check_is_required(ci.type_id, attr, '')

            existed_attrs = value_table.get_by(attr_id=attr.id,
                                               ci_id=ci.id,
                                               to_dict=False)
            existed_values = [i.value for i in existed_attrs]
            added = set(value_list) - set(existed_values)
            deleted = set(existed_values) - set(value_list)
            for v in added:
                value_table.create(ci_id=ci.id, attr_id=attr.id, value=v)
                self._write_change(ci.id, attr.id, OperateType.ADD, None, v)

            for v in deleted:
                existed_attr = existed_attrs[existed_values.index(v)]
                existed_attr.delete()
                self._write_change(ci.id, attr.id, OperateType.DELETE, v, None)
        else:
            value = self._validate(attr, value, value_table, ci)
            existed_attr = value_table.get_by(attr_id=attr.id,
                                              ci_id=ci.id,
                                              first=True,
                                              to_dict=False)
            existed_value = existed_attr and existed_attr.value
            if existed_value is None:
                value_table.create(ci_id=ci.id, attr_id=attr.id, value=value)
                self._write_change(ci.id, attr.id, OperateType.ADD, None,
                                   value)
            else:
                existed_attr.update(value=value)
                self._write_change(ci.id, attr.id, OperateType.UPDATE,
                                   existed_value, value)
Exemple #2
0
    def batch_update(cls, ci_ids, parents):
        """
        only for many to one
        :param ci_ids: 
        :param parents: 
        :return: 
        """
        from api.lib.cmdb.utils import TableMap

        if parents is not None and isinstance(parents, dict):
            for attr_name in parents:
                if parents[attr_name]:
                    attr = AttributeCache.get(attr_name)
                    value_table = TableMap(attr_name=attr.name).table
                    parent = value_table.get_by(attr_id=attr.id,
                                                value=parents[attr_name],
                                                first=True,
                                                to_dict=False)
                    if not parent:
                        return abort(
                            404, "{0}: {1} is not found".format(
                                attr_name, parents[attr_name]))
                    parent_id = parent.ci_id
                    for ci_id in ci_ids:
                        cls.add(parent_id, ci_id, many_to_one=True)
Exemple #3
0
    def delete(ci_id):
        ci = CI.get_by_id(ci_id) or abort(
            404, "CI <{0}> is not found".format(ci_id))

        attrs = CITypeAttribute.get_by(type_id=ci.type_id, to_dict=False)
        attr_names = set(
            [AttributeCache.get(attr.attr_id).name for attr in attrs])
        for attr_name in attr_names:
            value_table = TableMap(attr_name=attr_name).table
            for item in value_table.get_by(ci_id=ci_id, to_dict=False):
                item.delete()

        for item in CIRelation.get_by(first_ci_id=ci_id, to_dict=False):
            ci_relation_delete.apply_async(args=(item.first_ci_id,
                                                 item.second_ci_id),
                                           queue=CMDB_QUEUE)
            item.delete()

        for item in CIRelation.get_by(second_ci_id=ci_id, to_dict=False):
            ci_relation_delete.apply_async(args=(item.first_ci_id,
                                                 item.second_ci_id),
                                           queue=CMDB_QUEUE)
            item.delete()

        ci.delete()  # TODO: soft delete

        AttributeHistoryManger.add(ci_id,
                                   [(None, OperateType.DELETE, None, None)])

        ci_delete.apply_async([ci.id], queue=CMDB_QUEUE)

        return ci_id
Exemple #4
0
    def get_attr_values(self, fields, ci_id, ret_key="name", unique_key=None, use_master=False):
        """

        :param fields:
        :param ci_id:
        :param ret_key: It can be name or alias
        :param unique_key: primary attribute
        :param use_master: Only for master-slave read-write separation
        :return:
        """
        res = dict()
        for field in fields:
            attr = self._get_attr(field)
            if not attr:
                continue

            value_table = TableMap(attr_name=attr.name).table
            rs = value_table.get_by(ci_id=ci_id,
                                    attr_id=attr.id,
                                    use_master=use_master,
                                    to_dict=False)
            field_name = getattr(attr, ret_key)

            if attr.is_list:
                res[field_name] = [ValueTypeMap.serialize[attr.value_type](i.value) for i in rs]
            else:
                res[field_name] = ValueTypeMap.serialize[attr.value_type](rs[0].value) if rs else None

            if unique_key is not None and attr.id == unique_key.id and rs:
                res['unique'] = unique_key.name

        return res
Exemple #5
0
 def delete_attr_value(attr_id, ci_id):
     attr = AttributeCache.get(attr_id)
     if attr is not None:
         value_table = TableMap(attr_name=attr.name).table
         for item in value_table.get_by(attr_id=attr.id,
                                        ci_id=ci_id,
                                        to_dict=False):
             item.delete()
Exemple #6
0
 def ci_is_exist(unique_key, unique_value):
     """
     
     :param unique_key: is a attribute
     :param unique_value: 
     :return: 
     """
     value_table = TableMap(attr_name=unique_key.name).table
     unique = value_table.get_by(attr_id=unique_key.id,
                                 value=unique_value,
                                 to_dict=False,
                                 first=True)
     if unique:
         return CI.get_by_id(unique.ci_id)
Exemple #7
0
    def add_heartbeat(ci_type, unique_value):
        ci_type = CITypeManager().check_is_existed(ci_type)

        unique_key = AttributeCache.get(ci_type.unique_id)
        value_table = TableMap(attr_name=unique_key.name).table

        v = value_table.get_by(attr_id=unique_key.id,
                               value=unique_value,
                               to_dict=False,
                               first=True) \
            or abort(404, "not found")

        ci = CI.get_by_id(v.ci_id) or abort(404, "CI <{0}> is not found".format(v.ci_id))

        ci.update(heartbeat=datetime.datetime.now())
Exemple #8
0
    def create_or_update_attr_value(self,
                                    key,
                                    value,
                                    ci_id,
                                    _no_attribute_policy=ExistPolicy.IGNORE):
        """
        add or update attribute value, then write history
        :param key: id, name or alias
        :param value:
        :param ci_id:
        :param _no_attribute_policy: ignore or reject
        :return:
        """
        attr = self._get_attr(key)
        if attr is None:
            if _no_attribute_policy == ExistPolicy.IGNORE:
                return
            if _no_attribute_policy == ExistPolicy.REJECT:
                return abort(400, 'attribute {0} does not exist'.format(key))

        value_table = TableMap(attr_name=attr.name).table
        existed_attr = value_table.get_by(attr_id=attr.id,
                                          ci_id=ci_id,
                                          first=True,
                                          to_dict=False)
        existed_value = existed_attr and existed_attr.value
        operate_type = OperateType.ADD if existed_attr is None else OperateType.UPDATE

        value_list = handle_arg_list(value) if attr.is_list else [value]
        if not isinstance(value, list):
            value_list = [value]

        for v in value_list:
            v = self._validate(attr, v, value_table, ci_id)
            if not v and attr.value_type != ValueTypeEnum.TEXT:
                v = None

            if operate_type == OperateType.ADD:
                if v is not None:
                    value_table.create(ci_id=ci_id, attr_id=attr.id, value=v)
                    self._write_change(ci_id, attr.id, operate_type, None, v)
            elif existed_attr.value != v:
                if v is not None:
                    existed_attr.update(value=v)
                else:
                    existed_attr.delete()
                self._write_change(ci_id, attr.id, operate_type, existed_value,
                                   v)