mirror of
https://github.com/hanzoai/k8s.git
synced 2026-10-02 15:40:05 +00:00
The tree was staged but never committed — this is the repo's first commit, so it carries both the existing content and the zip v1.18.8 -> v1.20.0 migration. Migration: Prepare() is replaced by Build() error, and both test harnesses assert the verdict rather than discarding it. main.go:59's Use call needed no change — the three middleware constructors already return zip.Handler, which satisfies the closed Component interface. The committed projections (k8s.plugin.json, openapi.json, ops/zipdoc_gen.go) are regenerated: v1.20.0 splits an op's prose into summary (first line) + description and zipdoc now emits per-field docs, so all three artifacts move with the bump. Co-authored-by: Hanzo Dev <[email protected]>
72 lines
2.9 KiB
Go
72 lines
2.9 KiB
Go
// Command k8s is Hanzo's Kubernetes service: the ONE place in the fleet that holds a
|
|
// cluster credential and the ONE API — /v1/k8s — through which anything reaches a
|
|
// cluster.
|
|
//
|
|
// It builds as its own binary. A host composes it at run time; run directly it is an
|
|
// ordinary HIP-0119 service on its own port. Same binary, no second code path.
|
|
//
|
|
// # Why this is a service and not a library
|
|
//
|
|
// A cluster client linked into N apps means N binaries holding cluster credentials.
|
|
// Before this repo existed, nine places in the fleet built one: two with the ambient
|
|
// in-cluster ServiceAccount, one with a cluster-admin kubeconfig minted on demand for
|
|
// every cluster on the house account, and one with a kubeconfig read out of a database
|
|
// row and fed to a function that applied arbitrary YAML. That last one is the shape of
|
|
// the whole problem: with it, no ClusterRole smaller than "everything" could be
|
|
// written, so nothing was least-privileged and no reviewer could bound a blast radius.
|
|
//
|
|
// One owner, named ops, credentials in KMS. Consumers ASK.
|
|
//
|
|
// # Multi-cluster from the first line
|
|
//
|
|
// lux runs lux-k8s. zoo runs zoo-k8s. Customers run their own. So an org's resources
|
|
// may live on a different cluster from Hanzo's, and "our cluster" is not a thing this
|
|
// program can mean. Every op names its cluster, resolved through the registry against
|
|
// the calling org — and there is no ambient client to fall back to, because
|
|
// registry.Reach is the only client constructor in the module and it takes a name.
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/zap-proto/zip"
|
|
"github.com/zap-proto/zip/middleware"
|
|
|
|
"github.com/hanzoai/k8s/ops"
|
|
"github.com/hanzoai/k8s/registry"
|
|
)
|
|
|
|
// name is this app's ONE name: the binary, the socket stem, the Declaration name and
|
|
// the <org>-<app> IAM segment. No mapping table.
|
|
const name = "k8s"
|
|
|
|
// defaultAddr is where this serves when run DIRECTLY rather than by a host. Under a
|
|
// host, zip.Addr ignores it and uses the private socket the host created — which is the
|
|
// whole plugin side of the transport contract, and the reason a fixed bind here would
|
|
// make every child but the first die on "address already in use".
|
|
const defaultAddr = ":9663"
|
|
|
|
func main() {
|
|
if err := run(); err != nil {
|
|
fmt.Fprintf(os.Stderr, "%s: %v\n", name, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func run() error {
|
|
app := zip.New(zip.Config{AppName: name})
|
|
app.Use(middleware.Recover(), middleware.RequestID(), middleware.Logger(app.Logger()))
|
|
|
|
// The store is the KMS peer over the call plane. It is constructed, not dialed:
|
|
// zip.Ask dials lazily on first use, so nothing here touches a peer before the
|
|
// describe check below — which is required, because a projection is a function of
|
|
// the code and a describe run must not need a running fleet.
|
|
ops.Ops{Reg: registry.New(registry.Sealed{})}.Mount(app)
|
|
|
|
if done, err := app.Described(); done {
|
|
return err
|
|
}
|
|
return app.Listen(zip.Addr(defaultAddr))
|
|
}
|