You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
6.6 KiB

10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. from django.contrib import admin
  2. from django.core.paginator import Paginator
  3. from django.db import connection
  4. from hc.api.models import Channel, Check, Notification, Ping
  5. from hc.lib.date import format_duration
  6. class OwnershipListFilter(admin.SimpleListFilter):
  7. title = "Ownership"
  8. parameter_name = 'ownership'
  9. def lookups(self, request, model_admin):
  10. return (
  11. ('assigned', "Assigned"),
  12. )
  13. def queryset(self, request, queryset):
  14. if self.value() == 'assigned':
  15. return queryset.filter(user__isnull=False)
  16. return queryset
  17. @admin.register(Check)
  18. class ChecksAdmin(admin.ModelAdmin):
  19. class Media:
  20. css = {
  21. 'all': ('css/admin/checks.css',)
  22. }
  23. search_fields = ["name", "user__email", "code"]
  24. list_display = ("id", "name_tags", "created", "code", "timeout_schedule",
  25. "status", "email", "last_ping", "n_pings")
  26. list_select_related = ("user", )
  27. list_filter = ("status", OwnershipListFilter, "kind", "last_ping")
  28. actions = ["send_alert"]
  29. def email(self, obj):
  30. return obj.user.email if obj.user else None
  31. def name_tags(self, obj):
  32. if not obj.tags:
  33. return obj.name
  34. return "%s [%s]" % (obj.name, obj.tags)
  35. def timeout_schedule(self, obj):
  36. if obj.kind == "simple":
  37. return format_duration(obj.timeout)
  38. elif obj.kind == "cron":
  39. return obj.schedule
  40. else:
  41. return "Unknown"
  42. timeout_schedule.short_description = "Schedule"
  43. def send_alert(self, request, qs):
  44. for check in qs:
  45. check.send_alert()
  46. self.message_user(request, "%d alert(s) sent" % qs.count())
  47. send_alert.short_description = "Send Alert"
  48. class SchemeListFilter(admin.SimpleListFilter):
  49. title = "Scheme"
  50. parameter_name = 'scheme'
  51. def lookups(self, request, model_admin):
  52. return (
  53. ('http', "HTTP"),
  54. ('https', "HTTPS"),
  55. ('email', "Email"),
  56. )
  57. def queryset(self, request, queryset):
  58. if self.value():
  59. queryset = queryset.filter(scheme=self.value())
  60. return queryset
  61. class MethodListFilter(admin.SimpleListFilter):
  62. title = "Method"
  63. parameter_name = 'method'
  64. methods = ["HEAD", "GET", "POST", "PUT", "DELETE"]
  65. def lookups(self, request, model_admin):
  66. return zip(self.methods, self.methods)
  67. def queryset(self, request, queryset):
  68. if self.value():
  69. queryset = queryset.filter(method=self.value())
  70. return queryset
  71. # Adapted from: https://djangosnippets.org/snippets/2593/
  72. class LargeTablePaginator(Paginator):
  73. """ Overrides the count method to get an estimate instead of actual count
  74. when not filtered
  75. """
  76. def _get_estimate(self):
  77. try:
  78. cursor = connection.cursor()
  79. cursor.execute("SELECT reltuples FROM pg_class WHERE relname = %s",
  80. [self.object_list.query.model._meta.db_table])
  81. return int(cursor.fetchone()[0])
  82. except:
  83. return 0
  84. def _get_count(self):
  85. """
  86. Changed to use an estimate if the estimate is greater than 10,000
  87. Returns the total number of objects, across all pages.
  88. """
  89. if not hasattr(self, "_count") or self._count is None:
  90. try:
  91. estimate = 0
  92. if not self.object_list.query.where:
  93. estimate = self._get_estimate()
  94. if estimate < 10000:
  95. self._count = self.object_list.count()
  96. else:
  97. self._count = estimate
  98. except (AttributeError, TypeError):
  99. # AttributeError if object_list has no count() method.
  100. # TypeError if object_list.count() requires arguments
  101. # (i.e. is of type list).
  102. self._count = len(self.object_list)
  103. return self._count
  104. count = property(_get_count)
  105. @admin.register(Ping)
  106. class PingsAdmin(admin.ModelAdmin):
  107. search_fields = ("owner__name", "owner__code", "owner__user__email")
  108. list_select_related = ("owner", "owner__user")
  109. list_display = ("id", "created", "check_name", "email", "scheme", "method",
  110. "ua")
  111. list_filter = ("created", SchemeListFilter, MethodListFilter)
  112. paginator = LargeTablePaginator
  113. def check_name(self, obj):
  114. return obj.owner.name if obj.owner.name else obj.owner.code
  115. def email(self, obj):
  116. return obj.owner.user.email if obj.owner.user else None
  117. @admin.register(Channel)
  118. class ChannelsAdmin(admin.ModelAdmin):
  119. class Media:
  120. css = {
  121. 'all': ('css/admin/channels.css',)
  122. }
  123. search_fields = ["value", "user__email"]
  124. list_select_related = ("user", )
  125. list_display = ("id", "code", "email", "formatted_kind", "value",
  126. "num_notifications")
  127. list_filter = ("kind", )
  128. def email(self, obj):
  129. return obj.user.email if obj.user else None
  130. def formatted_kind(self, obj):
  131. if obj.kind == "pd":
  132. return "PagerDuty"
  133. elif obj.kind == "victorops":
  134. return "VictorOps"
  135. elif obj.kind == "pushbullet":
  136. return "Pushbullet"
  137. elif obj.kind == "discord":
  138. return "Discord"
  139. elif obj.kind == "po":
  140. return "Pushover"
  141. elif obj.kind == "webhook":
  142. return "Webhook"
  143. elif obj.kind == "slack":
  144. return "Slack"
  145. elif obj.kind == "hipchat":
  146. return "HipChat"
  147. elif obj.kind == "opsgenie":
  148. return "OpsGenie"
  149. elif obj.kind == "email" and obj.email_verified:
  150. return "Email"
  151. elif obj.kind == "email" and not obj.email_verified:
  152. return "Email <i>(unverified)</i>"
  153. else:
  154. raise NotImplementedError("Bad channel kind: %s" % obj.kind)
  155. formatted_kind.short_description = "Kind"
  156. formatted_kind.allow_tags = True
  157. def num_notifications(self, obj):
  158. return Notification.objects.filter(channel=obj).count()
  159. num_notifications.short_description = "# Notifications"
  160. @admin.register(Notification)
  161. class NotificationsAdmin(admin.ModelAdmin):
  162. search_fields = ["owner__name", "owner__code", "channel__value"]
  163. list_select_related = ("owner", "channel")
  164. list_display = ("id", "created", "check_status", "check_name",
  165. "channel_kind", "channel_value")
  166. list_filter = ("created", "check_status", "channel__kind")
  167. def check_name(self, obj):
  168. return obj.owner.name_then_code()
  169. def channel_kind(self, obj):
  170. return obj.channel.kind
  171. def channel_value(self, obj):
  172. return obj.channel.value