Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /swf-monitor/src/monitor_app/viewdir/declared_api.py was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 """GET /api/declared/ — the declared record as its out-of-process readers
0002 take it (swf-epicprod docs/CONTINUOUS_PRODUCTION.md, Declared downtime):
0003 per queue and per endpoint, the rule in force now with its line, the
0004 next window coming, the spans the target was declared over (each to its
0005 end or clearing plus the pilot's cache lag) and the latest span end.
0006 The site canary's provider reads this (site-canary canary/declared.py),
0007 so a standalone process needs no ORM. Anonymous, read-only.
0008 """
0009 from django.utils import timezone
0010 from rest_framework.decorators import api_view, authentication_classes, permission_classes
0011 from rest_framework.permissions import AllowAny
0012 from rest_framework.response import Response
0013 
0014 from ..declared import _dt, _iso, canary_declared, declared_for, summary_line
0015 
0016 
0017 @api_view(['GET'])
0018 @authentication_classes([])
0019 @permission_classes([AllowAny])
0020 def declared_state(request):
0021     now = timezone.now()
0022     out = {'now': _iso(now), 'queues': {}, 'endpoints': {}}
0023     for kind, key in (('queue', 'queues'), ('endpoint', 'endpoints')):
0024         current = declared_for(kind, now=now)
0025         names = sorted(current)
0026         spans = canary_declared(None, now) if kind == 'queue' else {}
0027         for target in names:
0028             slot = current[target]
0029             coming = slot['future'][0] if slot['future'] else None
0030             out[key][target] = {
0031                 'in_force': summary_line(slot['active'][0]) if slot['active'] else '',
0032                 'coming': summary_line(coming) if coming else '',
0033                 'coming_at': _iso(_dt(coming.get('start'))) if coming else None,
0034                 'line': slot.get('line', ''),
0035                 'spans': (spans.get(target) or {}).get('spans', []),
0036                 'last_end': (spans.get(target) or {}).get('last_end'),
0037             }
0038         if kind == 'queue':
0039             # Targets with only past spans (no rule in force, none coming)
0040             # still matter to a reader placing a sample window in time.
0041             for target, info in spans.items():
0042                 out[key].setdefault(target, {
0043                     'in_force': '', 'coming': '', 'coming_at': None, 'line': '',
0044                     'spans': info.get('spans', []), 'last_end': info.get('last_end')})
0045     return Response(out)
0046 
0047 
0048 @api_view(['GET'])
0049 @authentication_classes([])
0050 @permission_classes([AllowAny])
0051 def storage_doors(request):
0052     """GET /api/storage-doors/ — the storage door canary's record as the
0053     last cycle stored it (site-canary docs/STORAGE_DOORS.md): every door,
0054     its verdict and evidence, the certificate it serves, and a
0055     valid_until so a reader can tell a current reading from a stale one.
0056     Anonymous, read-only; a 503 until a cycle has run. Nothing acts on
0057     this record — it is read by people and by the node guard, which uses
0058     it only to excuse a node for a door's failures."""
0059     from monitor_app.models import CachedProduct
0060     from monitor_app.panda.storage_doors import STATE_KEY
0061     row = CachedProduct.objects.filter(key=STATE_KEY).first()
0062     if row is None or not row.value:
0063         return Response({'error': 'no storage door record stored yet'}, status=503)
0064     return Response(row.value)
0065 
0066 
0067 @api_view(['GET'])
0068 @authentication_classes([])
0069 @permission_classes([AllowAny])
0070 def node_guard_exclusion(request):
0071     """GET /api/node-guard/exclusion/ — the node guard's published
0072     exclusion as the last cycle stored it (site-canary docs/NODE_GUARD.md,
0073     Actuation): the same document the cycle puts on the bucket's pilot
0074     prefix. Anonymous, read-only; a 503 until a cycle has run."""
0075     from monitor_app.models import CachedProduct
0076     from monitor_app.panda.node_guard import EXCLUSION_KEY
0077     row = CachedProduct.objects.filter(key=EXCLUSION_KEY).first()
0078     if row is None or not row.value:
0079         return Response({'error': 'no exclusion document stored yet'}, status=503)
0080     return Response(row.value)