def _list_services(param): live = sites.live() columns = verify_columns(Services, param['columns']) q = Query(columns) host_name = param.get('host_name') if host_name is not None: q = q.filter(Services.host_name == host_name) filter_tree = param.get('query') if filter_tree: expr = tree_to_expr(filter_tree, Services.__tablename__) q = q.filter(expr) result = q.iterate(live) return constructors.serve_json( constructors.collection_object( domain_type='service', value=[ constructors.domain_object( domain_type='service', title=f"{entry['description']} on {entry['host_name']}", identifier=entry['description'], editable=False, deletable=False, extensions=entry, ) for entry in result ], ))
def _set_acknowlegement_on_queried_hosts( connection, query: str, sticky: bool, notify: bool, persistent: bool, comment: str, ): q = Query([Hosts.name, Hosts.state]).filter(tree_to_expr(query, Hosts.__tablename__)) hosts = list(q.iterate(connection)) if not hosts: return problem(status=404, title="The provided query returned no monitored hosts") for host in hosts: if host.state == 0: continue acknowledge_host_problem( connection, host.name, sticky=sticky, notify=notify, persistent=persistent, user=_user_id(), comment=comment, ) return http.Response(status=204)
def show_downtimes(param): """Show all scheduled downtimes""" live = sites.live() sites_to_query = param.get('sites') if sites_to_query: live.only_sites = sites_to_query q = Query([ Downtimes.id, Downtimes.host_name, Downtimes.service_description, Downtimes.is_service, Downtimes.author, Downtimes.start_time, Downtimes.end_time, Downtimes.recurring, Downtimes.comment, ]) filter_tree = param.get('query') host_name = param.get('host_name') service_description = param.get('service_description') if filter_tree is not None: expr = tree_to_expr(filter_tree) q = q.filter(expr) if host_name is not None: q = q.filter(Downtimes.host_name.contains(host_name)) if service_description is not None: q = q.filter( Downtimes.service_description.contains(service_description)) gen_downtimes = q.iterate(live) return _serve_downtimes(gen_downtimes)
def list_hosts(param): """Show hosts of specific condition""" live = sites.live() sites_to_query = param['sites'] if sites_to_query: live.only_sites = sites_to_query columns = verify_columns(Hosts, param['columns']) q = Query(columns) # TODO: add sites parameter filter_tree = param.get('query') if filter_tree: expr = tree_to_expr(filter_tree) q = q.filter(expr) result = q.iterate(live) return constructors.serve_json( constructors.collection_object( domain_type='host', value=[ constructors.domain_object( domain_type='host', title=f"{entry['name']}", identifier=entry['name'], editable=False, deletable=False, extensions=entry, ) for entry in result ], ))
def schedule_hosts_downtimes_with_query( connection, query: str, start_time: dt.datetime, end_time: dt.datetime, recur: RecurMode = 'fixed', duration: int = 0, user_id: str = '', comment: str = '', ): """Schedule a downtimes for hosts based upon a query""" q = Query([Hosts.name]).filter(tree_to_expr(query, Hosts.__tablename__)) hosts = [row['name'] for row in q.iterate(connection)] if not comment: comment = f"Downtime for hosts {', '.join(hosts)}" schedule_host_downtime( connection, host_name=hosts, start_time=start_time, end_time=end_time, recur=recur, duration=duration, user_id=user_id, comment=comment, )
def schedule_services_downtimes_with_query( connection, query, start_time: dt.datetime, end_time: dt.datetime, recur: RecurMode = 'fixed', duration: int = 0, user_id: str = '', comment: str = '', ): """Schedule downtimes for services based upon a query""" q = Query([Services.description, Services.host_name]).filter(tree_to_expr(query, Services.__tablename__)) for host_name, service_description in [ (row['host_name'], row['description']) for row in q.iterate(connection) ]: if not comment: downtime_comment = f"Downtime for service {service_description}@{host_name}" else: downtime_comment = comment schedule_service_downtime( connection, host_name=host_name, service_description=service_description, start_time=start_time, end_time=end_time, recur=recur, duration=duration, user_id=user_id, comment=downtime_comment, )
def delete_downtime_with_query(connection, query): """Delete scheduled downtimes based upon a query""" q = Query([Downtimes.id, Downtimes.is_service]).filter(tree_to_expr(query)) for downtime_id, is_service in [(row['id'], row['is_service']) for row in q.iterate(connection)]: if is_service: del_service_downtime(connection, downtime_id) else: del_host_downtime(connection, downtime_id)
def set_acknowledgement_on_service_related(params): """Set acknowledgement on related services""" body = params['body'] live = sites.live() sticky = body['sticky'] notify = body['notify'] persistent = body['persistent'] comment = body['comment'] acknowledge_type = body['acknowledge_type'] if acknowledge_type == 'service': return _set_acknowledgement_for_service( live, unquote(body['service_description']), sticky, notify, persistent, comment, ) if acknowledge_type == 'servicegroup': acknowledge_servicegroup_problem( live, body['servicegroup_name'], sticky=sticky, notify=notify, persistent=persistent, user=_user_id(), comment=comment, ) return http.Response(status=204) if acknowledge_type == 'service_by_query': q = Query([Services.host_name, Services.description, Services.state]).filter( tree_to_expr(body['query'], Services.__tablename__)) return _set_acknowledgement_on_queried_services( live, [(row['host_name'], row['description']) for row in q.iterate(live) if row['state'] > 0], sticky=sticky, notify=notify, persistent=persistent, comment=comment, ) return problem( status=400, title="Unhandled acknowledge-type.", detail=f"The acknowledge-type {acknowledge_type!r} is not supported.")
def load(self, data, *, many=None, partial=None, unknown=None): # When being passed in via the query string, we may get the raw JSON string instead of # the deserialized dictionary. We need to unpack it ourselves. if isinstance(data, str): try: data = json.loads(data) except json.decoder.JSONDecodeError as exc: raise ValidationError({ '_schema': [ f"Invalid JSON value: '{data}'", str(exc), ], }) elif isinstance(data, QueryExpression): return data if not self.context or 'table' not in self.context: raise RuntimeError(f"No table in context for field {self}") try: tree_to_expr(data, self.context['table']) except ValueError as e: raise ValidationError(str(e)) from e return super().load(data, many=many, partial=partial, unknown=unknown)
def _set_acknowledgement_for_service( connection, service_description: str, sticky: bool, notify: bool, persistent: bool, comment: str, ): q = Query([Services.host_name, Services.description, Services.state]).filter( tree_to_expr({ 'op': '=', 'left': 'services.description', 'right': service_description })) services = list(q.iterate(connection)) if not len(services): return problem( status=404, title=f'No services with {service_description!r} were found.', ) for service in services: if service.state == 0: continue acknowledge_service_problem( connection, service.host_name, service.description, sticky=sticky, notify=notify, persistent=persistent, user=_user_id(), comment=comment, ) return http.Response(status=204)
def _load(self, value, data, partial=None): _data = super()._load(value, data, partial=partial) return tree_to_expr(_data, table=self.metadata['table'])