| 1 | package host |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "strings" |
| 6 | |
| 7 | "github.com/carlosframework/platform/internal/hostbox" |
| 8 | "github.com/carlosframework/platform/internal/hostclaim" |
| 9 | "github.com/carlosframework/platform/internal/park" |
| 10 | "github.com/carlosframework/platform/internal/provision" |
| 11 | "github.com/carlosframework/platform/internal/release" |
| 12 | ) |
| 13 | |
| 14 | // The park fakes the moves tests inject (Plan 5 Task 9a). Production has no |
| 15 | // stand-in for the claim's view or authorizers; these are the rules the |
| 16 | // stand-ins had, kept for the tests that do not exercise the real view |
| 17 | // (movesParkView, movessources_test.go). The rest is the claim's own, as |
| 18 | // claim Plan 12 landed it (Q10): the claim's lease set and AggregateLeases over the tests' lease |
| 19 | // table, park.Engine.RunHeld, and the MoveParks local authorizer's wrapper. |
| 20 | |
| 21 | // standInView is the tests' park view: the location's objects classified by |
| 22 | // key, seen from region, and the other side of the move authoritative, which |
| 23 | // §5.1's table says it is before this side's probe is admitted (every install |
| 24 | // phase). role names this side (ruling J24): a landing (roleTarget) works |
| 25 | // while the source's region, From, is authoritative; a dirty return |
| 26 | // (roleSource) while the target's, To, is. |
| 27 | func standInView(region, role string, m *provision.MoveState) func(context.Context, hostclaim.Observed) (park.View, error) { |
| 28 | return func(_ context.Context, obs hostclaim.Observed) (park.View, error) { |
| 29 | if obs.Absent || obs.Claim == nil || obs.Claim.Holder == nil || m == nil { |
| 30 | return park.View{}, park.ErrUnsafe |
| 31 | } |
| 32 | var authoritative string |
| 33 | switch role { |
| 34 | case roleTarget: |
| 35 | authoritative = park.PlacementRegion(m.From) |
| 36 | case roleSource: |
| 37 | authoritative = park.PlacementRegion(m.To) |
| 38 | default: |
| 39 | return park.View{}, park.ErrUnsafe |
| 40 | } |
| 41 | location := strings.TrimSuffix(obs.Claim.Holder.Location, "/") |
| 42 | return park.View{ClaimETag: obs.ETag, Region: region, AuthoritativeRegion: authoritative, |
| 43 | GenerationOf: func(r park.Ref) (string, bool) { return landingGenerationOf(location, r.Key) }}, nil |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | // recordView is standInView over the record's move as the store holds it |
| 48 | // when the engine asks. |
| 49 | func recordView(s release.Store, region, role string) func(context.Context, hostclaim.Observed) (park.View, error) { |
| 50 | return func(ctx context.Context, obs hostclaim.Observed) (park.View, error) { |
| 51 | if obs.Absent || obs.Claim == nil || obs.Claim.Holder == nil { |
| 52 | return park.View{}, park.ErrUnsafe |
| 53 | } |
| 54 | h := obs.Claim.Holder |
| 55 | rec, err := provision.GetRecord(ctx, s, h.Account, h.App, obs.Host) |
| 56 | if err != nil { |
| 57 | return park.View{}, err |
| 58 | } |
| 59 | return standInView(region, role, rec.Move)(ctx, obs) |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | // allowParkAuthorize is the tests' claim authorizer: it allows every chore, |
| 64 | // so each arm's own operation check (movesArmAuthorize) decides alone. |
| 65 | func allowParkAuthorize(context.Context, hostclaim.Observed, hostclaim.Obligation) error { return nil } |
| 66 | |
| 67 | // allowLocalAuthorize is the claim's MoveParks local authorizer |
| 68 | // (claimMoveLocalAuthorizer, M9) over an identity check that passes and the |
| 69 | // allowing owner: it allows every park-local and refuses anything else. |
| 70 | var allowLocalAuthorize = claimMoveLocalAuthorizer(func(context.Context) error { return nil }, allowParkAuthorize) |
| 71 | |
| 72 | // claimParkLeases is the claim's park leases over the tests' lease table |
| 73 | // leases: AggregateLeases with the replica park lease set (M6), as the |
| 74 | // claim's MoveParks engine resolves them, lending a held lease to RunHeld. |
| 75 | func claimParkLeases(leases park.Leases) park.Leases { |
| 76 | return hostbox.AggregateLeases{Leases: leases, Resolve: hostbox.ReplicaParkLeaseSet} |
| 77 | } |
| 78 | |
| 79 | // armParkFakes arms c's park hooks: the claim's leases over the tests' |
| 80 | // lease table, the record-backed stand-in view for region and role, the |
| 81 | // allowing claim authorizer, park.Engine.RunHeld (movesRunHeld, M5) and the |
| 82 | // claim's local authorizer over the allowing owner. |
| 83 | func armParkFakes(c *moveCfg, s release.Store, leases park.Leases, region, role string) { |
| 84 | c.ParkLeases = claimParkLeases(leases) |
| 85 | c.ParkView = recordView(s, region, role) |
| 86 | c.ParkAuthorize = allowParkAuthorize |
| 87 | c.ParkRunHeld = movesRunHeld |
| 88 | c.ParkLocalAuthorize = allowLocalAuthorize |
| 89 | } |
| 90 | |