expression.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. # -*- coding:utf-8 -*-
  2. # Copyright 2017 Xiaomi, Inc.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. __author__ = 'Ulric Qin'
  16. from .bean import Bean
  17. from rrd.config import MAINTAINERS
  18. from rrd.model.portal.action import Action
  19. from rrd.model.user import User
  20. class Expression(Bean):
  21. _tbl = 'expression'
  22. _cols = 'id, expression, func, op, right_value, max_step, priority, note, action_id, create_user, pause'
  23. def __init__(self, _id, expression, func, op, right_value, max_step, priority, note, action_id,
  24. create_user, pause):
  25. self.id = _id
  26. self.expression = expression
  27. self.func = func
  28. self.op = op
  29. self.right_value = right_value
  30. self.max_step = max_step
  31. self.priority = priority
  32. self.note = note
  33. self.action_id = action_id
  34. self.create_user = create_user
  35. self.pause = pause
  36. self.action = None
  37. @classmethod
  38. def save_or_update(cls, expression_id, expression, func, op, right_value, uic_groups, max_step, priority, note, url,
  39. callback, before_callback_sms, before_callback_mail,
  40. after_callback_sms, after_callback_mail, login_user):
  41. if not expression.startswith('each('):
  42. return 'only support each expression. e.g. each(metric=? xx=yy)'
  43. if not 'metric=' in expression:
  44. return 'expression is invalid. e.g. each(metric=? xx=yy)'
  45. left = expression.find('(')
  46. right = expression.find(')')
  47. if left <= 0:
  48. return 'left parentheses ( not found'
  49. if right <= 0:
  50. return 'right parentheses ) not found'
  51. in_parentheses = expression[left + 1:right]
  52. in_parentheses = ' '.join(in_parentheses.replace(',', ' ').replace(';', ' ').split())
  53. arr = in_parentheses.split()
  54. arr = [item for item in arr if '=' in item]
  55. if len(arr) < 2:
  56. return 'expression is invalid. e.g. each(metric=? xx=yy)'
  57. expression = 'each(%s)' % in_parentheses
  58. if expression_id:
  59. return cls.update_expression(expression_id, expression, func, op, right_value, uic_groups, max_step,
  60. priority, note, url,
  61. callback, before_callback_sms, before_callback_mail,
  62. after_callback_sms, after_callback_mail)
  63. else:
  64. return cls.insert_expression(expression, func, op, right_value, uic_groups, max_step,
  65. priority, note, url, callback,
  66. before_callback_sms, before_callback_mail,
  67. after_callback_sms, after_callback_mail, login_user)
  68. @classmethod
  69. def insert_expression(cls, content, func, op, right_value, uic_groups, max_step, priority, note, url,
  70. callback, before_callback_sms, before_callback_mail,
  71. after_callback_sms, after_callback_mail, user_name):
  72. action_id = Action.insert({
  73. 'uic': uic_groups,
  74. 'url': url,
  75. 'callback': callback,
  76. 'before_callback_sms': before_callback_sms,
  77. 'before_callback_mail': before_callback_mail,
  78. 'after_callback_sms': after_callback_sms,
  79. 'after_callback_mail': after_callback_mail,
  80. })
  81. if not action_id:
  82. return 'save action fail'
  83. expression_id = Expression.insert({
  84. 'expression': content,
  85. 'func': func,
  86. 'op': op,
  87. 'right_value': right_value,
  88. 'max_step': max_step,
  89. 'priority': priority,
  90. 'note': note,
  91. 'action_id': action_id,
  92. 'create_user': user_name
  93. })
  94. if expression_id:
  95. return ''
  96. return 'save expression fail'
  97. @classmethod
  98. def update_expression(cls, expression_id, content, func, op, right_value, uic_groups, max_step, priority, note, url,
  99. callback, before_callback_sms, before_callback_mail,
  100. after_callback_sms, after_callback_mail):
  101. e = Expression.get(expression_id)
  102. if not e:
  103. return 'no such expression %s' % expression_id
  104. a = Action.get(e.action_id)
  105. if not a:
  106. return 'no relation action'
  107. Action.update_dict(
  108. {
  109. 'uic': uic_groups,
  110. 'url': url,
  111. 'callback': callback,
  112. 'before_callback_sms': before_callback_sms,
  113. 'before_callback_mail': before_callback_mail,
  114. 'after_callback_sms': after_callback_sms,
  115. 'after_callback_mail': after_callback_mail
  116. },
  117. 'id=%s',
  118. [a.id]
  119. )
  120. Expression.update_dict(
  121. {
  122. 'expression': content,
  123. 'func': func,
  124. 'op': op,
  125. 'right_value': right_value,
  126. 'max_step': max_step,
  127. 'priority': priority,
  128. 'note': note,
  129. },
  130. 'id=%s',
  131. [e.id]
  132. )
  133. return ''
  134. @classmethod
  135. def query(cls, page, limit, query, me=None):
  136. where = ''
  137. params = []
  138. if me is not None:
  139. where = 'create_user = %s'
  140. params.append(me)
  141. if query:
  142. where += ' and ' if where else ''
  143. where += 'expression like %s'
  144. params.append('%' + query + '%')
  145. vs = cls.select_vs(where=where, params=params, page=page, limit=limit)
  146. total = cls.total(where=where, params=params)
  147. return vs, total
  148. def writable(self, login_user):
  149. #login_user can be str or User obj
  150. if isinstance(login_user, str):
  151. login_user = User.get_by_name(login_user)
  152. if not login_user:
  153. return False
  154. if login_user.is_admin() or login_user.is_root():
  155. return True
  156. if self.create_user == login_user.name:
  157. return True
  158. if login_user.name in MAINTAINERS:
  159. return True
  160. a = self.action
  161. if not a:
  162. return False
  163. if not a.uic:
  164. return False
  165. return login_user.in_teams(a.uic)
  166. def to_json(self):
  167. return {
  168. "id": self.id,
  169. "expression": self.expression,
  170. "func": self.func,
  171. "op": self.op,
  172. "right_value": self.right_value,
  173. "max_step": self.max_step,
  174. "priority": self.priority,
  175. "note": self.note,
  176. "action_id": self.action_id
  177. }