diff --git a/go/seats/nodeengine/contract.go b/go/seats/nodeengine/contract.go index f8267e8..b0d565a 100644 --- a/go/seats/nodeengine/contract.go +++ b/go/seats/nodeengine/contract.go @@ -8,6 +8,7 @@ import ( "encoding/json" "errors" "strings" + "time" ) // Seat is the seat's name. @@ -348,7 +349,7 @@ func DecodeFindingsByKeyValue(raw []byte) (FindingsByKeyValue, error) { // AccountsHanded is the hashes of the users of the list, sealed to the vault. type AccountsHanded struct { // when - At string `json:"at"` + At time.Time `json:"at"` Box SealedBox `json:"box"` From string `json:"from"` // the fingerprint of the vault's key @@ -557,8 +558,8 @@ type FailedUnit struct { Result string `json:"result,omitempty"` Scope string `json:"scope"` // since when - Since string `json:"since"` - Unit string `json:"unit"` + Since time.Time `json:"since"` + Unit string `json:"unit"` } // FindingAction is one answer the operator may give from a notification. @@ -579,8 +580,8 @@ const ( // FindingEvidence is one observation, as it was said. type FindingEvidence struct { - At string `json:"at"` - Said string `json:"said"` + At time.Time `json:"at"` + Said string `json:"said"` } // FindingSubject is what the condition is about. @@ -598,10 +599,10 @@ type FindingSubject struct { // LoginFallback is a login that fell back to another node. type LoginFallback struct { // when - At string `json:"at"` - From string `json:"from"` - Node string `json:"node"` - Why string `json:"why"` + At time.Time `json:"at"` + From string `json:"from"` + Node string `json:"node"` + Why string `json:"why"` } // ManifestReadsChanged is what a node-engine says when what it reads changed or its node returned (ADR 0618 §4). @@ -651,7 +652,7 @@ const ( type NetworkHealth struct { Parts []NetworkPart `json:"parts"` // since when - Since string `json:"since"` + Since time.Time `json:"since"` // running, degraded or unknown State string `json:"state"` } @@ -663,12 +664,12 @@ type NetworkPart struct { Reason string `json:"reason,omitempty"` Said string `json:"said,omitempty"` // since when - Since string `json:"since"` - State string `json:"state"` - Streak int64 `json:"streak,omitempty"` - Targets []string `json:"targets,omitempty"` - Toward []string `json:"toward,omitempty"` - Writer string `json:"writer,omitempty"` + Since time.Time `json:"since"` + State string `json:"state"` + Streak int64 `json:"streak,omitempty"` + Targets []string `json:"targets,omitempty"` + Toward []string `json:"toward,omitempty"` + Writer string `json:"writer,omitempty"` } // NodeAccount is an account the node needs to log in again. @@ -678,7 +679,7 @@ type NodeAccount struct { Reason string `json:"reason"` Resource string `json:"resource,omitempty"` // since when - Since string `json:"since"` + Since time.Time `json:"since"` } // NodeDirectory is a directory found where the node expected none. @@ -688,7 +689,7 @@ type NodeDirectory struct { Reason string `json:"reason"` Resource string `json:"resource"` // since when - Since string `json:"since"` + Since time.Time `json:"since"` } // NodeOwn is what a node's own composition carries beside its resources. @@ -744,14 +745,14 @@ type PlacedDataItem struct { // PullWait is the pull from a store a failed apply waits on. type PullWait struct { // when the pull began - Began string `json:"began"` + Began time.Time `json:"began"` // that seat's holder, whose settling the apply waits for Holder string `json:"holder"` Image string `json:"image"` // what triggered the last try again, in words Retried string `json:"retried,omitempty"` // when the apply was last tried again - RetriedAt string `json:"retried-at,omitempty"` + RetriedAt *time.Time `json:"retried-at,omitempty"` // the seat the pull came through Seat string `json:"seat,omitempty"` } @@ -779,8 +780,8 @@ type RootAccountVerdict struct { Reason string `json:"reason,omitempty"` Resource string `json:"resource"` // since when - Since string `json:"since"` - State string `json:"state"` + Since time.Time `json:"since"` + State string `json:"state"` } // RootVerdict is the engine's root-free verdict (ADR 0563 §6). @@ -859,7 +860,7 @@ type UnitsHealth struct { // UserListWritten is the bus's user list as the engine of the bus node wrote it to the bus module's file. type UserListWritten struct { // when - At string `json:"at"` + At time.Time `json:"at"` // the digest of the file on the machine after the write Digest string `json:"digest,omitempty"` // why a write failed @@ -1361,7 +1362,7 @@ type PackagesByNodeValue struct { // HealthByNodeValue is one value of the state health under the key . type HealthByNodeValue struct { // when - At string `json:"at"` + At time.Time `json:"at"` Contract int64 `json:"contract,omitempty"` Fallback *LoginFallback `json:"fallback,omitempty"` Found []NodeDirectory `json:"found,omitempty"` @@ -1377,7 +1378,7 @@ type HealthByNodeValue struct { // FindingsByKeyValue is one value of the state findings under the key . type FindingsByKeyValue struct { Actions []FindingAction `json:"actions,omitempty"` - At string `json:"at"` + At time.Time `json:"at"` // newest first, at most 10 Evidence []FindingEvidence `json:"evidence,omitempty"` Explanation string `json:"explanation,omitempty"` diff --git a/health-and-repair/go/clients/meshconditionsclient/client.go b/health-and-repair/go/clients/meshconditionsclient/client.go index 8e3a014..2931dc8 100644 --- a/health-and-repair/go/clients/meshconditionsclient/client.go +++ b/health-and-repair/go/clients/meshconditionsclient/client.go @@ -146,7 +146,7 @@ func CheckFinding(f seat.FindingsByKeyValue) error { // Order sorts conditions as a person reads them: urgent first, then oldest raised, then by key. func Order(list []seat.ConditionsByKeyValue) { - raised := func(c seat.ConditionsByKeyValue) time.Time { t, _ := time.Parse(time.RFC3339Nano, c.Raised); return t } + raised := func(c seat.ConditionsByKeyValue) time.Time { return c.Raised } sort.SliceStable(list, func(i, j int) bool { if list[i].Severity != list[j].Severity { return list[i].Severity == Urgent @@ -163,8 +163,8 @@ func SilencedAt(c seat.ConditionsByKeyValue, now time.Time) bool { if c.Silenced == nil { return false } - until, err := time.Parse(time.RFC3339Nano, c.Silenced.Until) - return err == nil && now.Before(until) + until := c.Silenced.Until + return until != nil && now.Before(*until) } // Escalated says the condition waits on the operator after healers tried. @@ -191,7 +191,7 @@ var _ views.FindingWriter = FindingWriter{} // FindingFor is the value and key of the seat's finding for f. func FindingFor(f views.Finding) seat.FindingsByKeyValue { - at := f.At.UTC().Format(time.RFC3339Nano) + at := f.At.UTC() return seat.FindingsByKeyValue{V: FindingVersion, Key: Key(ScopeModule, f.ID, f.Kind), Kind: f.Kind, Subject: seat.Subject{Scope: ScopeModule, ID: f.ID}, Severity: Warning, Summary: f.Summary, Headline: f.Headline, Explanation: f.Explanation, Evidence: []seat.Evidence{{At: at, Said: f.Summary}}, Source: f.Observer + "." + f.Kind, diff --git a/health-and-repair/go/clients/meshconditionsclient/client_test.go b/health-and-repair/go/clients/meshconditionsclient/client_test.go index 746368a..c9ba6df 100644 --- a/health-and-repair/go/clients/meshconditionsclient/client_test.go +++ b/health-and-repair/go/clients/meshconditionsclient/client_test.go @@ -41,9 +41,9 @@ func TestAFindingsKeyAndTheOrderOfConditions(t *testing.T) { } } list := []seat.ConditionsByKeyValue{ - {Key: "b", Severity: Warning, Raised: "2026-11-01T10:00:00Z"}, - {Key: "c", Severity: Urgent, Raised: "2026-11-02T10:00:00Z"}, - {Key: "a", Severity: Urgent, Raised: "2026-11-01T10:00:00.5Z", Silenced: &seat.ConditionsByKeyValueSilenced{Until: "2026-11-03T00:00:00Z"}}, + {Key: "b", Severity: Warning, Raised: when("2026-11-01T10:00:00Z")}, + {Key: "c", Severity: Urgent, Raised: when("2026-11-02T10:00:00Z")}, + {Key: "a", Severity: Urgent, Raised: when("2026-11-01T10:00:00.5Z"), Silenced: &seat.ConditionsByKeyValueSilenced{Until: ptr(when("2026-11-03T00:00:00Z"))}}, } Order(list) if got := list[0].Key + list[1].Key + list[2].Key; got != "acb" { @@ -99,3 +99,13 @@ func TestTheFindingWriterWritesAndClearsAModulesFindingInTheSeatsLayout(t *testi t.Error("a finding that says nothing was written") } } + +func when(s string) time.Time { + t, err := time.Parse(time.RFC3339Nano, s) + if err != nil { + panic(err) + } + return t +} + +func ptr(t time.Time) *time.Time { return &t } diff --git a/health-and-repair/go/seats/meshconditions/contract.go b/health-and-repair/go/seats/meshconditions/contract.go index eddd19d..0757680 100644 --- a/health-and-repair/go/seats/meshconditions/contract.go +++ b/health-and-repair/go/seats/meshconditions/contract.go @@ -7,6 +7,7 @@ import ( "bytes" "encoding/json" "errors" + "time" ) // Seat is the seat's name. @@ -134,50 +135,50 @@ const ( // ConditionEventGapsItem is a type of the contract. type ConditionEventGapsItem struct { - Cleared string `json:"cleared,omitempty"` - Reopened string `json:"reopened,omitempty"` + Cleared *time.Time `json:"cleared,omitempty"` + Reopened *time.Time `json:"reopened,omitempty"` } // ConditionEventSilenced is a type of the contract. type ConditionEventSilenced struct { - By string `json:"by,omitempty"` - Since string `json:"since,omitempty"` - Until string `json:"until,omitempty"` - Why string `json:"why,omitempty"` + By string `json:"by,omitempty"` + Since *time.Time `json:"since,omitempty"` + Until *time.Time `json:"until,omitempty"` + Why string `json:"why,omitempty"` } // ConditionEventTriedItem is a type of the contract. type ConditionEventTriedItem struct { - At string `json:"at,omitempty"` - By string `json:"by,omitempty"` - Outcome string `json:"outcome,omitempty"` - What string `json:"what,omitempty"` + At *time.Time `json:"at,omitempty"` + By string `json:"by,omitempty"` + Outcome string `json:"outcome,omitempty"` + What string `json:"what,omitempty"` } // ConditionEvent is a condition and what changed. type ConditionEvent struct { - Actions []Action `json:"actions,omitempty"` - At string `json:"at"` - Change string `json:"change"` - Cleared string `json:"cleared,omitempty"` - Count int64 `json:"count,omitempty"` - Epoch int64 `json:"epoch,omitempty"` - Event string `json:"event"` + Actions []Action `json:"actions,omitempty"` + At time.Time `json:"at"` + Change string `json:"change"` + Cleared *time.Time `json:"cleared,omitempty"` + Count int64 `json:"count,omitempty"` + Epoch int64 `json:"epoch,omitempty"` + Event string `json:"event"` // newest first, at most 10 Evidence []Evidence `json:"evidence,omitempty"` Explanation string `json:"explanation,omitempty"` - First string `json:"first,omitempty"` + First *time.Time `json:"first,omitempty"` Gaps []ConditionEventGapsItem `json:"gaps,omitempty"` Headline string `json:"headline,omitempty"` // scope.id.token - Key string `json:"key"` - Kind string `json:"kind,omitempty"` - LastObserved string `json:"last-observed,omitempty"` - LooksUnread string `json:"looks-unread,omitempty"` - Needs string `json:"needs,omitempty"` - Observations int64 `json:"observations,omitempty"` - Raised string `json:"raised,omitempty"` - Resolved string `json:"resolved,omitempty"` + Key string `json:"key"` + Kind string `json:"kind,omitempty"` + LastObserved *time.Time `json:"last-observed,omitempty"` + LooksUnread string `json:"looks-unread,omitempty"` + Needs string `json:"needs,omitempty"` + Observations int64 `json:"observations,omitempty"` + Raised *time.Time `json:"raised,omitempty"` + Resolved string `json:"resolved,omitempty"` // self, operator, agent or healer: Resolver string `json:"resolver,omitempty"` Severity string `json:"severity,omitempty"` @@ -214,8 +215,8 @@ const ( // Evidence is one observation, as it was said. type Evidence struct { - At string `json:"at"` - Said string `json:"said"` + At time.Time `json:"at"` + Said string `json:"said"` } // Subject is what the condition is about. @@ -288,24 +289,24 @@ type ConditionClearedEvent = ConditionEvent // ConditionsByKeyValueGapsItem is a type of the contract. type ConditionsByKeyValueGapsItem struct { - Cleared string `json:"cleared,omitempty"` - Reopened string `json:"reopened,omitempty"` + Cleared *time.Time `json:"cleared,omitempty"` + Reopened *time.Time `json:"reopened,omitempty"` } // ConditionsByKeyValueSilenced is a type of the contract. type ConditionsByKeyValueSilenced struct { - By string `json:"by,omitempty"` - Since string `json:"since,omitempty"` - Until string `json:"until,omitempty"` - Why string `json:"why,omitempty"` + By string `json:"by,omitempty"` + Since *time.Time `json:"since,omitempty"` + Until *time.Time `json:"until,omitempty"` + Why string `json:"why,omitempty"` } // ConditionsByKeyValueTriedItem is a type of the contract. type ConditionsByKeyValueTriedItem struct { - At string `json:"at,omitempty"` - By string `json:"by,omitempty"` - Outcome string `json:"outcome,omitempty"` - What string `json:"what,omitempty"` + At *time.Time `json:"at,omitempty"` + By string `json:"by,omitempty"` + Outcome string `json:"outcome,omitempty"` + What string `json:"what,omitempty"` } // ConditionsByKeyValue is one value of the state conditions under the key . @@ -316,18 +317,18 @@ type ConditionsByKeyValue struct { // newest first, at most 10 Evidence []Evidence `json:"evidence,omitempty"` Explanation string `json:"explanation,omitempty"` - First string `json:"first,omitempty"` + First *time.Time `json:"first,omitempty"` Gaps []ConditionsByKeyValueGapsItem `json:"gaps,omitempty"` Headline string `json:"headline,omitempty"` // scope.id.token - Key string `json:"key"` - Kind string `json:"kind"` - LastObserved string `json:"last-observed"` - LooksUnread string `json:"looks-unread,omitempty"` - Needs string `json:"needs,omitempty"` - Observations int64 `json:"observations,omitempty"` - Raised string `json:"raised"` - Resolved string `json:"resolved,omitempty"` + Key string `json:"key"` + Kind string `json:"kind"` + LastObserved time.Time `json:"last-observed"` + LooksUnread string `json:"looks-unread,omitempty"` + Needs string `json:"needs,omitempty"` + Observations int64 `json:"observations,omitempty"` + Raised time.Time `json:"raised"` + Resolved string `json:"resolved,omitempty"` // self, operator, agent or healer: Resolver string `json:"resolver,omitempty"` Severity string `json:"severity"` @@ -348,8 +349,8 @@ const ( // FindingsByKeyValue is one value of the state findings under the key . type FindingsByKeyValue struct { - Actions []Action `json:"actions,omitempty"` - At string `json:"at"` + Actions []Action `json:"actions,omitempty"` + At time.Time `json:"at"` // newest first, at most 10 Evidence []Evidence `json:"evidence,omitempty"` Explanation string `json:"explanation,omitempty"` diff --git a/health-and-repair/go/seats/meshhandacts/contract.go b/health-and-repair/go/seats/meshhandacts/contract.go index dfe00ce..12c84db 100644 --- a/health-and-repair/go/seats/meshhandacts/contract.go +++ b/health-and-repair/go/seats/meshhandacts/contract.go @@ -8,6 +8,7 @@ import ( "encoding/json" "errors" "strings" + "time" ) // Seat is the seat's name. @@ -116,9 +117,9 @@ func DecodeWarrantsByAskerAskValue(raw []byte) (WarrantsByAskerAskValue, error) // Act is one act done by hand. type Act struct { - Arguments []string `json:"arguments,omitempty"` - Ask string `json:"ask,omitempty"` - At string `json:"at"` + Arguments []string `json:"arguments,omitempty"` + Ask string `json:"ask,omitempty"` + At time.Time `json:"at"` // the caller the runtime proved By string `json:"by"` Carried []string `json:"carried,omitempty"` @@ -191,9 +192,9 @@ type ActRecordedEvent = Act // ActsByIDValue is one value of the state acts under the key . type ActsByIDValue struct { - Arguments []string `json:"arguments,omitempty"` - Ask string `json:"ask,omitempty"` - At string `json:"at"` + Arguments []string `json:"arguments,omitempty"` + Ask string `json:"ask,omitempty"` + At time.Time `json:"at"` // the caller the runtime proved By string `json:"by"` Carried []string `json:"carried,omitempty"` @@ -214,9 +215,9 @@ type ActsByIDValue struct { // WarrantsByAskerAskValue is one value of the state warrants under the key .. type WarrantsByAskerAskValue struct { - Ask string `json:"ask"` - Asker string `json:"asker"` - At string `json:"at,omitempty"` - By string `json:"by,omitempty"` - Option string `json:"option,omitempty"` + Ask string `json:"ask"` + Asker string `json:"asker"` + At *time.Time `json:"at,omitempty"` + By string `json:"by,omitempty"` + Option string `json:"option,omitempty"` } diff --git a/health-and-repair/go/seats/meshhealers/contract.go b/health-and-repair/go/seats/meshhealers/contract.go index b26eaaf..4733ebc 100644 --- a/health-and-repair/go/seats/meshhealers/contract.go +++ b/health-and-repair/go/seats/meshhealers/contract.go @@ -7,6 +7,7 @@ import ( "bytes" "encoding/json" "errors" + "time" ) // Seat is the seat's name. @@ -143,17 +144,17 @@ type DrillAnswer = map[string]any // HealerActedEvent is the body of the event healer-acted. type HealerActedEvent struct { - Act string `json:"act,omitempty"` - At string `json:"at"` - Budget string `json:"budget,omitempty"` - By string `json:"by,omitempty"` - Condition string `json:"condition"` - Event string `json:"event"` - Healer string `json:"healer"` - Kind string `json:"kind,omitempty"` - Outcome string `json:"outcome"` - Said string `json:"said,omitempty"` - Show string `json:"show,omitempty"` + Act string `json:"act,omitempty"` + At time.Time `json:"at"` + Budget string `json:"budget,omitempty"` + By string `json:"by,omitempty"` + Condition string `json:"condition"` + Event string `json:"event"` + Healer string `json:"healer"` + Kind string `json:"kind,omitempty"` + Outcome string `json:"outcome"` + Said string `json:"said,omitempty"` + Show string `json:"show,omitempty"` } // The values of HealerActedEvent's outcome. @@ -166,16 +167,16 @@ const ( // AttemptsByAttemptValue is one value of the state attempts under the key . type AttemptsByAttemptValue struct { - Act string `json:"act"` - Begun string `json:"begun"` + Act string `json:"act"` + Begun time.Time `json:"begun"` // what the budget counts by: the condition's key unless the healer says another - BudgetKey string `json:"budget-key"` - Condition string `json:"condition"` - Finished string `json:"finished,omitempty"` - Healer string `json:"healer"` - Kind string `json:"kind"` - Outcome string `json:"outcome"` - Said string `json:"said,omitempty"` + BudgetKey string `json:"budget-key"` + Condition string `json:"condition"` + Finished *time.Time `json:"finished,omitempty"` + Healer string `json:"healer"` + Kind string `json:"kind"` + Outcome string `json:"outcome"` + Said string `json:"said,omitempty"` } // The values of AttemptsByAttemptValue's outcome. @@ -188,10 +189,10 @@ const ( // WouldByWouldValue is one value of the state would under the key . type WouldByWouldValue struct { - Act string `json:"act"` - At string `json:"at"` - Condition string `json:"condition"` - Healer string `json:"healer"` - Kind string `json:"kind,omitempty"` - Why string `json:"why,omitempty"` + Act string `json:"act"` + At time.Time `json:"at"` + Condition string `json:"condition"` + Healer string `json:"healer"` + Kind string `json:"kind,omitempty"` + Why string `json:"why,omitempty"` } diff --git a/health-and-repair/go/seats/meshselfcheck/contract.go b/health-and-repair/go/seats/meshselfcheck/contract.go index 2c67551..ad3b5cb 100644 --- a/health-and-repair/go/seats/meshselfcheck/contract.go +++ b/health-and-repair/go/seats/meshselfcheck/contract.go @@ -3,6 +3,8 @@ // Package meshselfcheck is the contract of the seat "mesh-self-check", defined whole (seats/mesh-self-check/seat.json): The mesh checking itself (ADR 0564): probes run every five minutes, each failure a finding the seat's conditions raise. package meshselfcheck +import "time" + // Seat is the seat's name. const Seat = "mesh-self-check" @@ -88,13 +90,13 @@ type CheckedEventCounts struct { // CheckedEvent is the body of the event checked. type CheckedEvent struct { - At string `json:"at"` + At time.Time `json:"at"` Controller string `json:"controller,omitempty"` Counts *CheckedEventCounts `json:"counts,omitempty"` IntervalSeconds int64 `json:"interval-seconds,omitempty"` Probes []ProbeVerdict `json:"probes"` Run string `json:"run"` - Started string `json:"started,omitempty"` + Started *time.Time `json:"started,omitempty"` Took string `json:"took,omitempty"` Unsaid int64 `json:"unsaid,omitempty"` Why string `json:"why,omitempty"` diff --git a/health-and-repair/go/seats/meshwatchdogs/contract.go b/health-and-repair/go/seats/meshwatchdogs/contract.go index 05c76ca..286d7dd 100644 --- a/health-and-repair/go/seats/meshwatchdogs/contract.go +++ b/health-and-repair/go/seats/meshwatchdogs/contract.go @@ -8,6 +8,7 @@ import ( "encoding/json" "errors" "strings" + "time" ) // Seat is the seat's name. @@ -258,9 +259,9 @@ type StuckByBucketKeyValue struct { Bucket string `json:"bucket"` Key string `json:"key"` // it has moved again - Moved bool `json:"moved,omitempty"` - Since string `json:"since"` - V int64 `json:"v,omitempty"` + Moved bool `json:"moved,omitempty"` + Since time.Time `json:"since"` + V int64 `json:"v,omitempty"` // what it waited for, in words Waited string `json:"waited,omitempty"` } diff --git a/identity-and-access/go/clients/meshvaultclient/client_test.go b/identity-and-access/go/clients/meshvaultclient/client_test.go index 2c00bf5..77dba63 100644 --- a/identity-and-access/go/clients/meshvaultclient/client_test.go +++ b/identity-and-access/go/clients/meshvaultclient/client_test.go @@ -36,7 +36,7 @@ func TestSigningNodeLoginsAndOwnDrift(t *testing.T) { } // A node's two logins: the first, the second, a rotation to the other only, a stage only with a rotation. - since := "2026-11-02T01:00:00Z" + since := time.Date(2026, 11, 2, 1, 0, 0, 0, time.UTC) for name, c := range map[string]struct { l seat.NodeLoginsByNodeValue ok bool @@ -56,7 +56,7 @@ func TestSigningNodeLoginsAndOwnDrift(t *testing.T) { } else if back, err := DecodeNodeLogin(raw); err != nil || Rotates(back) { t.Errorf("round trip: %+v %v", back, err) } - if _, err := DecodeNodeLogin([]byte(`{"v":9,"node":"g14","login":"node.g14","since":"` + since + `"}`)); err == nil { + if _, err := DecodeNodeLogin([]byte(`{"v":9,"node":"g14","login":"node.g14","since":"` + since.Format(time.RFC3339) + `"}`)); err == nil { t.Error("version 9 was taken") } if n, ok := LoginNode("node.g14--b"); !ok || n != "g14" { diff --git a/identity-and-access/go/clients/meshvaultclient/signers.go b/identity-and-access/go/clients/meshvaultclient/signers.go index 1ef79ce..476b4e6 100644 --- a/identity-and-access/go/clients/meshvaultclient/signers.go +++ b/identity-and-access/go/clients/meshvaultclient/signers.go @@ -87,7 +87,7 @@ func ParseCertificate(text string) (*x509.Certificate, error) { // NewSignerKey is the value of `key` for pub. func NewSignerKey(pub ed25519.PublicKey, made time.Time) seat.SignersByKeyValue { - return seat.SignersByKeyValue{V: 1, Key: base64.StdEncoding.EncodeToString(pub), Fingerprint: SignerFingerprint(pub), Made: made.UTC().Format(time.RFC3339Nano)} + return seat.SignersByKeyValue{V: 1, Key: base64.StdEncoding.EncodeToString(pub), Fingerprint: SignerFingerprint(pub), Made: made.UTC()} } // PublicKey is k's key, checked: an ed25519 public key whose fingerprint is the one k names. diff --git a/identity-and-access/go/seats/meshnodeenroller/contract.go b/identity-and-access/go/seats/meshnodeenroller/contract.go index 3cdab36..fc7f677 100644 --- a/identity-and-access/go/seats/meshnodeenroller/contract.go +++ b/identity-and-access/go/seats/meshnodeenroller/contract.go @@ -8,6 +8,7 @@ import ( "encoding/json" "errors" "strings" + "time" ) // Seat is the seat's name. @@ -137,14 +138,14 @@ func DecodeEnrolmentsByAddressAddressValue(raw []byte) (EnrolmentsByAddressAddre // Enrolment is one open enrolment. type Enrolment struct { - Address string `json:"address"` - Ask string `json:"ask,omitempty"` - Caller string `json:"caller,omitempty"` - Expires string `json:"expires,omitempty"` - Issued string `json:"issued,omitempty"` - KeysDigest string `json:"keys-digest,omitempty"` - Node string `json:"node"` - OverlayKey string `json:"overlay-key,omitempty"` + Address string `json:"address"` + Ask string `json:"ask,omitempty"` + Caller string `json:"caller,omitempty"` + Expires *time.Time `json:"expires,omitempty"` + Issued *time.Time `json:"issued,omitempty"` + KeysDigest string `json:"keys-digest,omitempty"` + Node string `json:"node"` + OverlayKey string `json:"overlay-key,omitempty"` // asked, live or redeeming Stage string `json:"stage"` V int64 `json:"v,omitempty"` @@ -266,8 +267,8 @@ type EnrolmentsByNodeNodeValue = Enrolment // EnrolmentsByAddressAddressValue is one value of the state enrolments under the key address.
. type EnrolmentsByAddressAddressValue struct { - Ask string `json:"ask,omitempty"` - Issued string `json:"issued,omitempty"` - Node string `json:"node"` - V int64 `json:"v,omitempty"` + Ask string `json:"ask,omitempty"` + Issued *time.Time `json:"issued,omitempty"` + Node string `json:"node"` + V int64 `json:"v,omitempty"` } diff --git a/identity-and-access/go/seats/meshvault/contract.go b/identity-and-access/go/seats/meshvault/contract.go index 2f3fe11..9d51257 100644 --- a/identity-and-access/go/seats/meshvault/contract.go +++ b/identity-and-access/go/seats/meshvault/contract.go @@ -8,6 +8,7 @@ import ( "encoding/json" "errors" "strings" + "time" ) // Seat is the seat's name. @@ -539,18 +540,18 @@ type OwnRetiredHolderEvent struct { type SignersByKeyValue struct { Fingerprint string `json:"fingerprint"` // the signing key's public half, standard base64 - Key string `json:"key"` - Made string `json:"made"` - V int64 `json:"v,omitempty"` + Key string `json:"key"` + Made time.Time `json:"made"` + V int64 `json:"v,omitempty"` } // SignersByAuthorityValue is one value of the state signers under the key authority. type SignersByAuthorityValue struct { // the authority certificate, PEM - Certificate string `json:"certificate"` - Fingerprint string `json:"fingerprint"` - Made string `json:"made"` - V int64 `json:"v,omitempty"` + Certificate string `json:"certificate"` + Fingerprint string `json:"fingerprint"` + Made time.Time `json:"made"` + V int64 `json:"v,omitempty"` } // NodeLoginsByNodeValue is one value of the state node-logins under the key . @@ -562,8 +563,8 @@ type NodeLoginsByNodeValue struct { Login string `json:"login"` Node string `json:"node"` // the login rotating to, empty when none - Rotating string `json:"rotating,omitempty"` - Since string `json:"since"` + Rotating string `json:"rotating,omitempty"` + Since time.Time `json:"since"` // begun, ready or confirmed; empty when no rotation Stage string `json:"stage,omitempty"` V int64 `json:"v,omitempty"` diff --git a/placement/go/seats/meshmoduleassigner/contract.go b/placement/go/seats/meshmoduleassigner/contract.go index 843340f..85f9ec8 100644 --- a/placement/go/seats/meshmoduleassigner/contract.go +++ b/placement/go/seats/meshmoduleassigner/contract.go @@ -8,6 +8,7 @@ import ( "encoding/json" "errors" "strings" + "time" ) // Seat is the seat's name. @@ -403,9 +404,9 @@ type Placement struct { // PlacementEventWarrant is who approved it, through which channel, when. type PlacementEventWarrant struct { - At string `json:"at"` - Warrant string `json:"warrant"` - Words string `json:"words"` + At time.Time `json:"at"` + Warrant string `json:"warrant"` + Words string `json:"words"` } // PlacementEvent is what each placement event carries. @@ -421,9 +422,9 @@ type PlacementEvent struct { // Proposal is an open proposal. type Proposal struct { - Again string `json:"again,omitempty"` - Ask string `json:"ask,omitempty"` - At string `json:"at"` + Again *time.Time `json:"again,omitempty"` + Ask string `json:"ask,omitempty"` + At time.Time `json:"at"` // by node whose key it changes, the revision of the key it was laid over (0: none) Base map[string]int64 `json:"base"` By string `json:"by"` @@ -434,14 +435,14 @@ type Proposal struct { Must []string `json:"must,omitempty"` Seed bool `json:"seed,omitempty"` // answering, failed or asked - State string `json:"state"` - V int64 `json:"v,omitempty"` - Verdict *Verdict `json:"verdict,omitempty"` - Warrant *Warrant `json:"warrant,omitempty"` - Why string `json:"why"` - Withdrawn string `json:"withdrawn,omitempty"` - Words string `json:"words,omitempty"` - Written string `json:"written,omitempty"` + State string `json:"state"` + V int64 `json:"v,omitempty"` + Verdict *Verdict `json:"verdict,omitempty"` + Warrant *Warrant `json:"warrant,omitempty"` + Why string `json:"why"` + Withdrawn string `json:"withdrawn,omitempty"` + Words string `json:"words,omitempty"` + Written *time.Time `json:"written,omitempty"` } // ProposalChangeKeys is the public halves of a joining node's keys. @@ -507,7 +508,7 @@ type SeatHolders struct { type Verdict struct { // every node's answer to its candidate, by node Answers map[string]map[string]any `json:"answers,omitempty"` - At string `json:"at"` + At time.Time `json:"at"` Carried map[string][]string `json:"carried,omitempty"` Fails []string `json:"fails,omitempty"` Intended map[string][]string `json:"intended,omitempty"` @@ -516,7 +517,7 @@ type Verdict struct { // waits, pass or fail State string `json:"state"` Unintended map[string][]string `json:"unintended,omitempty"` - Until string `json:"until,omitempty"` + Until *time.Time `json:"until,omitempty"` } // Warrant is the enrolment's warrant an add-node carries. diff --git a/provisioning/go/seats/meshprovisioner/contract.go b/provisioning/go/seats/meshprovisioner/contract.go index 3d54da9..7e2325e 100644 --- a/provisioning/go/seats/meshprovisioner/contract.go +++ b/provisioning/go/seats/meshprovisioner/contract.go @@ -8,6 +8,7 @@ import ( "encoding/json" "errors" "strings" + "time" ) // Seat is the seat's name. @@ -217,16 +218,16 @@ type ProvisionsByNodeConsumerProvisionValueReference struct { // ProvisionsByNodeConsumerProvisionValueWarrant is a type of the contract. type ProvisionsByNodeConsumerProvisionValueWarrant struct { - Ask string `json:"ask,omitempty"` - At string `json:"at,omitempty"` - By string `json:"by,omitempty"` - Option string `json:"option,omitempty"` + Ask string `json:"ask,omitempty"` + At *time.Time `json:"at,omitempty"` + By string `json:"by,omitempty"` + Option string `json:"option,omitempty"` } // ProvisionsByNodeConsumerProvisionValue is one value of the state provisions under the key ... type ProvisionsByNodeConsumerProvisionValue struct { Ask string `json:"ask,omitempty"` - At string `json:"at"` + At time.Time `json:"at"` Consumer ProvisionsByNodeConsumerProvisionValueConsumer `json:"consumer"` DependsOn []string `json:"depends-on,omitempty"` Local string `json:"local,omitempty"` @@ -289,16 +290,16 @@ type ProvisionsByNodeConsumerProvisionLocalValueReference struct { // ProvisionsByNodeConsumerProvisionLocalValueWarrant is a type of the contract. type ProvisionsByNodeConsumerProvisionLocalValueWarrant struct { - Ask string `json:"ask,omitempty"` - At string `json:"at,omitempty"` - By string `json:"by,omitempty"` - Option string `json:"option,omitempty"` + Ask string `json:"ask,omitempty"` + At *time.Time `json:"at,omitempty"` + By string `json:"by,omitempty"` + Option string `json:"option,omitempty"` } // ProvisionsByNodeConsumerProvisionLocalValue is one value of the state provisions under the key .... type ProvisionsByNodeConsumerProvisionLocalValue struct { Ask string `json:"ask,omitempty"` - At string `json:"at"` + At time.Time `json:"at"` Consumer ProvisionsByNodeConsumerProvisionLocalValueConsumer `json:"consumer"` DependsOn []string `json:"depends-on,omitempty"` Local string `json:"local,omitempty"`