carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package host
2
3import (
4 "context"
5 "maps"
6 "reflect"
7 "strconv"
8 "strings"
9 "time"
10
11 "github.com/carlosframework/platform/internal/hostbox"
12 "github.com/carlosframework/platform/internal/hostclaim"
13 "github.com/carlosframework/platform/internal/hostguard"
14 "github.com/carlosframework/platform/internal/hostops"
15 "github.com/carlosframework/platform/internal/park"
16)
17
18func (p productionClaimRegional) ordinaryHome(ctx context.Context, o hostclaim.Observed) (hostbox.Actor, string, error) {
19 a, err := p.Identity.Verify(ctx)
20 if err != nil {
21 return a, "", err
22 }
23 if o.Absent || o.ETag == "" || o.Claim == nil || o.Host != o.Claim.Host || o.Claim.Validate() != nil || p.Local == nil || p.Local.assembly == nil {
24 return a, "", park.ErrUnsafe
25 }
26 home, err := park.VerifiedHome(a.FleetHomeRegion, a.HomeRegion, a.Region, o.Claim.Op.Intent["home_region"])
27 if err != nil || a.FleetHomeRegion == "" || a.Region != a.FleetHomeRegion {
28 return a, "", park.ErrUnsafe
29 }
30 switch o.Claim.Op.Kind {
31 case hostclaim.KindServing, hostclaim.KindDeleting, hostclaim.KindParking:
32 default:
33 return a, "", park.ErrUnsafe
34 }
35 if h := o.Claim.Holder; h != nil {
36 if h.Location != "instances/"+o.Host+"/"+h.Incarnation || (o.Claim.Op.Exec != "" && o.Claim.Op.Exec != a.Box) {
37 return a, "", park.ErrUnsafe
38 }
39 for _, admission := range h.Admissions {
40 if admission.Box != a.Box || !park.SameRegion(home, admission.Region, a.Region) || (admission.PredecessorRegion != "" && !park.SameRegion(home, admission.PredecessorRegion, a.Region)) {
41 return a, "", park.ErrUnsafe
42 }
43 }
44 }
45 return a, home, nil
46}
47
48func (p productionClaimRegional) ordinaryView(ctx context.Context, o hostclaim.Observed) (park.View, error) {
49 a, home, err := p.ordinaryHome(ctx, o)
50 if err != nil {
51 return park.View{}, err
52 }
53 v := park.View{HomeRegion: home, ClaimETag: o.ETag, Region: park.PlacementRegion(a.Region), AuthoritativeRegion: movesNoLiveRegion,
54 ArchivedIncarnations: claimArchivedLocations(o.Claim), RefusedLocations: map[string]error{"moves/" + o.Host: park.ErrUnsafe}}
55 h := o.Claim.Holder
56 if h == nil {
57 return v, nil
58 }
59 v.GenerationOf = func(r park.Ref) (string, bool) { return landingGenerationOf(h.Location, r.Key) }
60 if o.Claim.Op.Kind == hostclaim.KindParking {
61 return v, nil
62 }
63 v.AuthoritativeRegion = a.Region
64 data := hostbox.RequestStore{Store: p.Local.assembly.Data, Check: claimBoundIdentity(p.Identity.Verify, a)}
65 listing, err := data.ListVersions(ctx, a.Bucket, h.Location+"/")
66 if err != nil {
67 return park.View{}, err
68 }
69 if err = readMarker(ctx, data, a.Bucket, o.Host, h.Location, *h, listing, &v); err != nil {
70 return park.View{}, err
71 }
72 databasePins := maps.Clone(v.Pinned)
73 if err = pinFilesLiveSet(ctx, data, a.Bucket, h.Location, listing, &v, liveGenerations(o.Claim, v)...); err != nil {
74 return park.View{}, err
75 }
76 v.FilePins = map[park.Ref]bool{}
77 for ref := range v.Pinned {
78 if !databasePins[ref] && strings.HasPrefix(ref.Key, h.Location+"/files/") {
79 v.FilePins[ref] = true
80 }
81 }
82 return v, nil
83}
84
85func (p productionClaimRegional) VerifyObligation(ctx context.Context, o hostclaim.Observed, ob hostclaim.Obligation) (hostclaim.ParkScope, error) {
86 if p.Parks != nil {
87 if evidence, ok := p.Parks.Evidence.(hostbox.RegionalObligationEvidence); ok {
88 return evidence.VerifyObligation(ctx, o, ob)
89 }
90 return hostclaim.ParkScope{}, park.ErrUnsafe
91 }
92 a, home, err := p.ordinaryHome(ctx, o)
93 if err != nil {
94 return hostclaim.ParkScope{}, err
95 }
96 c, h := o.Claim, o.Claim.Holder
97 if c.Op.Kind != hostclaim.KindServing || c.Op.ID != "" || h == nil || ob.Kind != "park-generation" || ob.Owner != "region:"+ob.Region || !park.SameRegion(home, ob.Region, a.Region) || ob.Box != "" || ob.ParkTarget != "" || len(ob.EvidenceRefs) != 0 || ob.Generation == "" || ob.Generation == h.Generation {
98 return hostclaim.ParkScope{}, park.ErrUnsafe
99 }
100 session, err := strconv.ParseUint(strings.TrimPrefix(ob.Op, "session:"), 10, 64)
101 if err != nil || ob.Op != "session:"+strconv.FormatUint(session, 10) || session == 0 || session > h.Session {
102 return hostclaim.ParkScope{}, park.ErrUnsafe
103 }
104 found := false
105 for _, live := range c.Obligations {
106 live.Park = ob.Park
107 if reflect.DeepEqual(live, ob) {
108 found = true
109 }
110 }
111 if !found {
112 return hostclaim.ParkScope{}, park.ErrChanged
113 }
114 guard := p.Local.assembly.Guard
115 if guard.Root == nil && guard.FenceView == nil {
116 return hostclaim.ParkScope{}, park.ErrUnsafe
117 }
118 var at time.Time
119 for _, admission := range h.Admissions {
120 if admission.Generation != ob.Generation {
121 continue
122 }
123 if admission.Mode != "cold" || admission.Session >= session {
124 return hostclaim.ParkScope{}, park.ErrUnsafe
125 }
126 receipts, err := guard.CompletedServingStops(ctx, o.Host, hostguard.Captured{Incarnation: h.Incarnation, Stamp: admission.Session}, admission.Session, a.Box)
127 if err != nil {
128 return hostclaim.ParkScope{}, err
129 }
130 for _, receipt := range receipts {
131 if !park.SameRegion(home, receipt.Target.Region, a.Region) || receipt.Target.Enrollment != a.Enrollment || receipt.EvidenceAt.IsZero() || verifyRetirementReceipt(ctx, receipt) != nil {
132 return hostclaim.ParkScope{}, park.ErrUnsafe
133 }
134 if ob.Park != nil {
135 if receipt.EvidenceAt.Equal(ob.Park.EvidenceAt) {
136 at = receipt.EvidenceAt
137 }
138 } else if receipt.EvidenceAt.After(at) {
139 at = receipt.EvidenceAt
140 }
141 }
142 }
143 if at.IsZero() {
144 return hostclaim.ParkScope{}, park.ErrUnsafe
145 }
146 scope := hostclaim.ParkScope{Location: h.Location, Incarnation: h.Incarnation, EvidenceAt: at, RequestLimit: hostbox.RequestLimit}
147 if ob.Park != nil && !reflect.DeepEqual(*ob.Park, scope) {
148 return hostclaim.ParkScope{}, park.ErrChanged
149 }
150 return scope, scope.Validate(o.Host)
151}
152
153func (p productionClaimRegional) authorizeOrdinaryRetirement(ctx context.Context, o hostclaim.Observed, ob hostclaim.Obligation) error {
154 a, _, err := p.ordinaryHome(ctx, o)
155 if err != nil {
156 return err
157 }
158 if o.Claim.Op.Kind != hostclaim.KindParking || o.Claim.Holder == nil || ob.Kind != "park-replica" || p.Local.assembly.RetirementAuthority == nil {
159 return park.ErrUnsafe
160 }
161 if ob.ParkTarget != o.Claim.Holder.Location {
162 if ob.ParkTarget != "moves/"+o.Host {
163 return park.ErrUnsafe
164 }
165 data := hostbox.RequestStore{Store: p.Local.assembly.Data, Check: claimBoundIdentity(p.Identity.Verify, a)}
166 versions, err := data.ListVersions(ctx, a.Bucket, ob.ParkTarget+"/")
167 if err != nil {
168 return err
169 }
170 for _, version := range versions {
171 if version.Key != ob.ParkTarget+"/lock.json" || version.VersionID == "" {
172 return park.ErrUnsafe
173 }
174 }
175 }
176 return (hostops.RetirementEvidence{Authority: *p.Local.assembly.RetirementAuthority}).VerifyBound(ctx, o, ob)
177}
178