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 "crypto/ed25519"
6 "net"
7 "net/http"
8 "strings"
9 "testing"
10 "time"
11
12 "github.com/carlosframework/platform/internal/hostactors"
13 "github.com/carlosframework/platform/internal/hostbox"
14 "github.com/carlosframework/platform/internal/hostops"
15 "github.com/carlosframework/platform/internal/hostwrite"
16 "github.com/carlosframework/platform/internal/release"
17)
18
19func TestPlan9CleanupEnrollmentDoesNotGrantExecution(t *testing.T) {
20 t.Parallel()
21 root := ed25519.NewKeyFromSeed(make([]byte, 32))
22 evidence := ed25519.NewKeyFromSeed([]byte(strings.Repeat("e", 32)))
23 actor := hostbox.Actor{Box: "box", Enrollment: strings.Repeat("a", 32), Revision: 1, Binding: "1", Region: "ie"}
24 identity := handoverRecoveryIdentity(t, actor)
25 cloudActor, err := identity.Roster.Actor(t.Context(), actor.Box)
26 if err != nil {
27 t.Fatal(err)
28 }
29 store := release.NewDirStore(t.TempDir())
30 row := hostactors.Box{BoxID: actor.Box, Enrollment: actor.Enrollment, Namespace: identity.Namespace, Label: actor.Box, Region: actor.Region, Pool: "default", Cloud: hostactors.Cloud{Provider: "aws", Account: cloudActor.Cloud.Account, Region: cloudActor.Cloud.Region, InstanceID: cloudActor.Cloud.InstanceID}, EvidenceSHA256: strings.Repeat("c", 64), CensusPublicKey: evidence.Public().(ed25519.PublicKey), State: "quarantined", QuarantineRevision: 1, LossIDs: []string{"loss"}}
31 roster := hostactors.Roster{V: 1, DeploymentBucket: "deployment", Revision: 1, RequestLimitNS: int64(hostbox.RequestLimit), Boxes: map[string]hostactors.Box{actor.Box: row}, Consoles: map[string]hostactors.Console{}, Holds: map[string]hostactors.Reservation{}, Activations: map[string]hostactors.Reservation{}}
32 write := func() {
33 raw, err := release.SignRootEnvelope(release.RootSigner(root), roster)
34 if err != nil {
35 t.Fatal(err)
36 }
37 _, etag, _ := store.Get(t.Context(), hostactors.Key)
38 if _, err = store.Put(t.Context(), hostactors.Key, raw, etag); err != nil {
39 t.Fatal(err)
40 }
41 }
42 write()
43 directory := hostactors.Directory{Store: store, PublicKey: root.Public().(ed25519.PublicKey), Bucket: "deployment"}
44 identity.Roster = productionClaimRoster{Directory: directory, DataBucket: identity.Bucket, FloorDir: t.TempDir()}
45 if _, err = identity.Verify(t.Context()); err == nil {
46 t.Fatal("quarantine granted work")
47 }
48 cleanup, err := verifyClaimCleanupEnrollment(t.Context(), identity, directory)
49 if err != nil {
50 t.Fatal(err)
51 }
52 if cleanup.actor.Eligible || !cleanup.actor.Quarantined {
53 t.Fatal("cleanup projection can grant execution")
54 }
55 authority := &hostops.ProductionAuthority{Store: store, Directory: directory, Now: time.Now}
56 owners := ClaimOwnerBindings{Identity: identity, cleanupEnrollment: cleanup, RetirementAuthority: authority, EvidenceKey: evidence}
57 if _, err = owners.actorForConstruction(t.Context(), "agent"); err == nil {
58 t.Fatal("agent used cleanup projection")
59 }
60 if _, err = owners.actorForConstruction(t.Context(), "adopt"); err == nil {
61 t.Fatal("adopt used cleanup projection")
62 }
63 if _, err = owners.actorForConstruction(t.Context(), "instance-control"); err != nil {
64 t.Fatal(err)
65 }
66 stop, err := owners.claimEvidenceCoordinator(t.Context(), store, "instance-control", cleanup.actor)
67 if err != nil || len(stop.EvidenceSigner) == 0 {
68 t.Fatalf("cleanup signer: %v", err)
69 }
70 owners.EvidenceKey = root
71 if _, err = owners.claimEvidenceCoordinator(t.Context(), store, "instance-control", cleanup.actor); err == nil {
72 t.Fatal("unenrolled key accepted")
73 }
74 row.Enrollment = strings.Repeat("b", 32)
75 roster.Boxes[actor.Box] = row
76 write()
77 if err = cleanup.configureSigner(t.Context(), stop, evidence); err == nil {
78 t.Fatal("old enrollment signed after replacement")
79 }
80}
81
82func TestPlan9RootWithdrawalRefusesNewHandover(t *testing.T) {
83 f := newRecoveryFixture(t)
84 controller := f.controller("boot-1", "controller-1", 4101, "start-1")
85 _ = controller
86 root := ClaimRootHTTP{RequireNewWork: func(context.Context) error { return hostwrite.ErrUnavailable }, Stop: ClaimStopHTTP{Coordinator: f.root(recoveryStopDrain{}), Authenticate: func(context.Context, net.Conn) (StopPeer, error) { return f.peer, nil }}}
87 socket := startRetirementRecoveryTransport(t, root)
88 if got := postRecoveryHandover(t, socket, coldHandoverRequest{}); got != http.StatusForbidden {
89 t.Fatalf("withdrawn handover=%d", got)
90 }
91}
92