feat: publish Tend v0.2 Preview 2 source
Export the reviewed allowlisted snapshot from private source commit 8aab3db43f35e6a49aa497f45d73701b13fc9f32 and tree 992132ea4703437dc13ffdbb04a077816c02caf9. This includes routed singleton continuity, deployment evidence, strict schema-2 configuration, restricted transport, and the independently compilable public-tree guard. AI-Assisted: OpenAI Codex Signed-off-by: Cole Speelman <crspeelman@gmail.com>
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
package eventlog
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
const Version = 1
|
||||
|
||||
var safeValue = regexp.MustCompile(`^[A-Za-z0-9._:/@+-]{1,256}$`)
|
||||
var hexDigest = regexp.MustCompile(`^[0-9a-f]{64}$`)
|
||||
var gitCommit = regexp.MustCompile(`^[0-9a-f]{40}$`)
|
||||
var operationID = regexp.MustCompile(`^[0-9a-f]{32}$`)
|
||||
|
||||
type Event struct {
|
||||
Version int `json:"version"`
|
||||
OperationID string `json:"operation_id"`
|
||||
Service string `json:"service"`
|
||||
ArtifactDigest string `json:"artifact_digest"`
|
||||
Commit string `json:"commit"`
|
||||
ReleaseVersion string `json:"release_version"`
|
||||
Phase string `json:"phase"`
|
||||
Slot string `json:"slot,omitempty"`
|
||||
DurationMillis int64 `json:"duration_ms"`
|
||||
Outcome string `json:"outcome"`
|
||||
ObservedAt string `json:"observed_at"`
|
||||
}
|
||||
|
||||
func OperationID() (string, error) {
|
||||
b := make([]byte, 16)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
return "", errors.New("cryptographic randomness unavailable")
|
||||
}
|
||||
return hex.EncodeToString(b), nil
|
||||
}
|
||||
|
||||
func Append(path string, event Event) error {
|
||||
if err := event.validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
if !filepath.IsAbs(path) || filepath.Clean(path) != path {
|
||||
return errors.New("event log path must be absolute and clean")
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0o750); err != nil {
|
||||
return fmt.Errorf("create event directory: %w", err)
|
||||
}
|
||||
if info, err := os.Lstat(path); err == nil {
|
||||
if !info.Mode().IsRegular() || info.Mode()&os.ModeSymlink != 0 || info.Mode().Perm()&0o022 != 0 {
|
||||
return errors.New("event log must be a non-writable regular non-symlink file")
|
||||
}
|
||||
} else if !errors.Is(err, os.ErrNotExist) {
|
||||
return fmt.Errorf("inspect event log: %w", err)
|
||||
}
|
||||
b, err := json.Marshal(event)
|
||||
if err != nil {
|
||||
return fmt.Errorf("encode deployment event: %w", err)
|
||||
}
|
||||
if len(b) > 4096 {
|
||||
return errors.New("deployment event exceeds bound")
|
||||
}
|
||||
b = append(b, '\n')
|
||||
fd, err := syscall.Open(path, syscall.O_WRONLY|syscall.O_APPEND|syscall.O_CREAT|syscall.O_CLOEXEC|syscall.O_NOFOLLOW, 0o640)
|
||||
if err != nil {
|
||||
return fmt.Errorf("open event log: %w", err)
|
||||
}
|
||||
file := os.NewFile(uintptr(fd), path)
|
||||
if file == nil {
|
||||
_ = syscall.Close(fd)
|
||||
return errors.New("open event log file")
|
||||
}
|
||||
defer file.Close()
|
||||
n, err := file.Write(b)
|
||||
if err != nil || n != len(b) {
|
||||
return errors.New("write complete deployment event")
|
||||
}
|
||||
if err := file.Sync(); err != nil {
|
||||
return fmt.Errorf("sync deployment event: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e Event) validate() error {
|
||||
if e.Version != Version || !operationID.MatchString(e.OperationID) {
|
||||
return errors.New("deployment event identity is invalid")
|
||||
}
|
||||
if !hexDigest.MatchString(e.ArtifactDigest) || !gitCommit.MatchString(e.Commit) {
|
||||
return errors.New("deployment event provenance is invalid")
|
||||
}
|
||||
for label, value := range map[string]string{"service": e.Service, "artifact_digest": e.ArtifactDigest, "commit": e.Commit, "release_version": e.ReleaseVersion, "phase": e.Phase, "outcome": e.Outcome} {
|
||||
if !safeValue.MatchString(value) || strings.ContainsRune(value, '\x00') {
|
||||
return fmt.Errorf("deployment event %s is invalid", label)
|
||||
}
|
||||
}
|
||||
if e.Slot != "" && !safeValue.MatchString(e.Slot) {
|
||||
return errors.New("deployment event slot is invalid")
|
||||
}
|
||||
if e.DurationMillis < 0 {
|
||||
return errors.New("deployment event duration is invalid")
|
||||
}
|
||||
if _, err := time.Parse(time.RFC3339Nano, e.ObservedAt); err != nil {
|
||||
return errors.New("deployment event timestamp is invalid")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user