carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package console
2
3import (
4 "context"
5 "encoding/json"
6 "net"
7 "net/http"
8 "strings"
9
10 "github.com/carlosframework/platform/internal/provision"
11)
12
13// appDefaultView is §9.3's app_default. region is the STORED region (what
14// deploy --region compares against); effective is where a no-region create
15// lands: the fleet itself for a placed app, never the platform home
16// (codex R2-4). RegionKnown and PlacementKnown say which facts were READ:
17// an unread fact is left empty, never filled with the home (codex
18// plan-R2 3; spec R9a). InstanceDomain is the domain instance hosts take,
19// so canary --region can name its host before any write (codex plan-R3 1).
20type appDefaultView struct {
21 Region string `json:"region"`
22 Name string `json:"name"`
23 Source string `json:"source"`
24 Effective string `json:"effective"`
25 Available *bool `json:"available,omitempty"`
26 Reason string `json:"reason,omitempty"`
27 RegionKnown bool `json:"region_known"`
28 PlacementKnown bool `json:"placement_known"`
29 InstanceDomain string `json:"instance_domain,omitempty"`
30}
31
32func boolp(b bool) *bool { return &b }
33
34func (s *Server) appDefault(ctx context.Context, acct *Account, app string) appDefaultView {
35 stored, source, rerr := s.appRegion(acct.ID, app)
36 snap, ferr := s.liveEdges(ctx)
37 cands := homeOnlyCandidates()
38 if ferr == nil {
39 cands = s.regionCands(snap)
40 }
41 pol := s.appPolicy(ctx, acct, app)
42 v := appDefaultView{RegionKnown: rerr == nil, PlacementKnown: pol.State != policyUnreadable}
43 switch pol.State {
44 case policyKnown:
45 v.InstanceDomain = pol.M.Domain
46 case policyAbsent:
47 v.InstanceDomain = s.platformInstanceDomain(acct)
48 }
49 if rerr == nil {
50 v.Region, v.Name, v.Source, v.Effective = s.homeRegionOut(stored), s.placeOf(stored, cands), source, s.homeRegionOut(stored)
51 }
52 switch {
53 case pol.State == policyUnreadable:
54 // policy-unreadable is reserved for placement_known being false
55 // (spec §9.3).
56 v.Reason = "policy-unreadable"
57 return v
58 case pol.Placed != "":
59 // R9a: with the stored region unread, effective stays empty even
60 // though the fleet is known; reason still says fleet (codex
61 // plan-R4 1).
62 v.Reason = "fleet"
63 if rerr == nil {
64 v.Effective = pol.Placed
65 }
66 return v
67 case pol.pooled():
68 // A no-region pooled create lands on the home, so it is available
69 // only when the home passes the allow-list (codex plan-R3 2). R9a
70 // again: nothing about effective is stated when the region is unread.
71 v.Reason = "pooled"
72 if rerr == nil {
73 v.Effective, v.Available = s.homeRegionOut(""), boolp(pol.allows(""))
74 }
75 return v
76 case rerr != nil:
77 // The stored region is unread, so where a create lands is unknown.
78 // Nothing is stated about it, and no reason either: the placement
79 // WAS read (controller ruling PF7).
80 return v
81 case ferr != nil, stored != "" && !snap.EvidenceComplete():
82 // A failed listing, or (for a non-home region) a listing with an
83 // edges file or a box snapshot unread: the evidence is not there
84 // to say the region can take an instance, and the create door
85 // would answer C28 for the same reason (re-review r1).
86 v.Reason = "edges-unreadable"
87 return v
88 }
89 reason := "absent"
90 if c, ok := findCandidate(cands, stored); ok {
91 reason = c.unavailableReason()
92 }
93 if reason == "" && !pol.allows(stored) {
94 reason = "not-allowed"
95 }
96 v.Reason, v.Available = reason, boolp(reason == "")
97 return v
98}
99
100// platformInstanceDomain is the domain the instances-manifest PUT stamps on
101// a NEW manifest (handleAPIInstancesEnable): "" when this console has no
102// valid platform apps domain, which that PUT refuses. With a manifest, its
103// own domain governs instead.
104func (s *Server) platformInstanceDomain(acct *Account) string {
105 if s.cfg.AppsDomain == "" {
106 return ""
107 }
108 d := acct.Sqid + "." + s.cfg.AppsDomain
109 if !provision.ValidHostShape(d) {
110 return ""
111 }
112 return d
113}
114
115// handleAPIRegionGuess is POST …/regions/guess (spec §9.4). Hints come only
116// in the body, so no redirect can echo them. A malformed body is read as
117// no hints; a person's request with no ip uses its own address, a service
118// principal's never does.
119//
120// A fleet-placed app gets no guess (codex R4-1), and a failed placement
121// lookup is an explicit 502, never a guess from a policy that was not read.
122func (s *Server) handleAPIRegionGuess(w http.ResponseWriter, r *http.Request) {
123 _, acct, app, ok := s.instanceGate(w, r)
124 if !ok {
125 return
126 }
127 var body struct {
128 TZ string `json:"tz"`
129 IP string `json:"ip"`
130 }
131 _ = json.NewDecoder(http.MaxBytesReader(w, r.Body, 64<<10)).Decode(&body)
132 pol := s.appPolicy(r.Context(), acct, app)
133 if pol.State == policyUnreadable {
134 jsonError(w, http.StatusBadGateway, msgPolicyUnreadable)
135 return
136 }
137 if pol.Placed != "" || pol.pooled() {
138 writeJSON(w, http.StatusOK, map[string]any{"guess": nil})
139 return
140 }
141 ip := net.ParseIP(strings.TrimSpace(body.IP))
142 if ip == nil {
143 ip = s.personIP(r)
144 }
145 files, err := s.liveEdges(r.Context())
146 cands := homeOnlyCandidates()
147 if err == nil {
148 cands = s.regionCands(files)
149 }
150 g, ok := guessRegion(cands, pol.allows, guessInput{TZ: body.TZ, IP: ip}, s.cfg.GeoIP)
151 if !ok {
152 writeJSON(w, http.StatusOK, map[string]any{"guess": nil})
153 return
154 }
155 writeJSON(w, http.StatusOK, map[string]any{"guess": map[string]string{
156 "code": s.homeRegionOut(g.Code), "name": s.placeOf(g.Code, cands), "source": g.Source,
157 }})
158}
159