Help us shape the future of Go! Take the 2026 Go Developer Survey

kitio

package
v0.54.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 22, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package kitio imports Git-owned stackkit.yaml definitions and generates reviewable CUE, Terraform, Docker Compose, and YAML artifacts.

Index

Constants

This section is empty.

Variables

View Source
var ApplicationToGroup = map[string]string{
	"photos":     "photo-management",
	"media":      "media-streaming",
	"vault":      "password-vault",
	"smart-home": "smart-home",
	"files":      "file-sharing",
	"ai":         "ai-workloads",
	"dev":        "dev-platform",
	"mail":       "mail-server",
	"game":       "game-server",
	"remote":     "remote-desktop",
}

ApplicationToGroup maps stackkit.yaml `application.<key>` to sk_service_group.slug. Pre-2026-04 named UseCaseToGroup with key `useCases.<key>`. See migration 000084.

View Source
var FoundationToGroup = map[string]string{
	"security-baseline": "security-baseline",
	"admin-bootstrap":   "admin-bootstrap",
}

FoundationToGroup maps stackkit.yaml `foundation.<key>` to sk_service_group.slug.

Note (migration 000085): `login-gateway` was previously here. Per ARCHITECTURE_V6 §4, login-gateway (TinyAuth + PocketID) is L2 Platform, not L1 Foundation — the admin bootstrap step is Foundation, the identity service itself is Platform. login-gateway moved to PlatformToGroup.

View Source
var PlatformToGroup = map[string]string{
	"traefik":       "reverse-proxy",
	"tinyauth":      "forward-auth",
	"login-gateway": "forward-auth",
	"pocketid":      "oidc-provider",
	"paas":          "paas",
	"monitoring":    "uptime-monitoring",
	"dashboard":     "dashboard",
	"dozzle":        "container-logs",
	"socket-proxy":  "docker-socket-proxy",
	"unbound":       "dns-resolver",
	"adguard-home":  "dns-filter",
	"crowdsec":      "intrusion-detection",
}

PlatformToGroup maps stackkit.yaml `platform.<key>` to sk_service_group.slug.

Functions

func CanonicalHash

func CanonicalHash(def KitDefinition) (string, error)

CanonicalHash returns sha256(canonical-json(def)) — same algorithm as the kit-import endpoint server-side. Used for drift detection + golden tests.

func ExportCUE

func ExportCUE(def KitDefinition) (stackfileBytes, servicesBytes []byte, err error)

ExportCUE renders a kit definition into CUE form.

Two outputs:

  • stackfileBytes: package <slug> with #StackKitConfig including metadata + supportedOS + modes + features.
  • servicesBytes: package <slug> with the per-service-group selections and per-tier sizing as commented-out placeholder records (the actual module CUE definitions live in modules/*/module.cue and are not duplicated here).

This is a *valid CUE* representation of the DB-shape — it is NOT meant to byte-equal the hand-written basement-kit/stackfile.cue, which carries hand-curated comments + schema constraints. The roundtrip test validates `cue eval` succeeds, not byte-equality.

func ExportCompose

func ExportCompose(def KitDefinition, outDir string) error

ExportCompose produces a Docker-Compose-style overview file at the kit level — NOT per-module compose fragments (those are generated by stackkit generate at deploy-time from the StackSpec + selected modules).

What this writes is a `kit-overview.compose.yml` that records the kit's service-group selections in compose-comment form, useful for operators who want to read what a kit "is" without running stackkit generate.

func ExportTerraform

func ExportTerraform(def KitDefinition, outDir string) error

ExportTerraform produces a `terraform.tfvars.json` from the kit definition's compute-tier requirements + selections + features.

This is intentionally a thin "kit-level" tfvars surface:

  • tier sizing -> tfvars (cpu, memory, disk per tier)
  • selected modules per group -> tfvars enable_<module> bool
  • features -> tfvars feature_<name> bool

Deployable OpenTofu/Compose output comes from canonical verified CUE generation (architecturev2 GenerationAuthorization.RenderAndInstall), not here. This export covers the kit-definition contract surface only — what a downstream installer needs to know about the kit's defaults.

func ExportYAML

func ExportYAML(def KitDefinition) ([]byte, error)

ExportYAML produces a stackkit.yaml byte representation of the kit definition. The output is structurally equivalent to the original stackkit.yaml — same sections, same keys, same nesting — modulo cosmetic ordering and whitespace.

Used by:

  • stackkit kit export (writes to disk)
  • stackkit kit roundtrip (compares against original)
  • kit_export_test.go golden tests

func SortedModeKeys

func SortedModeKeys(m map[string]ModeDef) []string

SortedModeKeys returns mode keys in stable order.

Types

type AddonsDef

type AddonsDef struct {
	AutoActivated []string `yaml:"autoActivated,omitempty" json:"autoActivated,omitempty"`
	Optional      []string `yaml:"optional,omitempty" json:"optional,omitempty"`
}

AddonsDef holds autoActivated + optional addon slug lists.

type ApplicationConnectorDef

type ApplicationConnectorDef struct {
	Kind          string   `yaml:"kind,omitempty" json:"kind,omitempty"`
	Name          string   `yaml:"name,omitempty" json:"name,omitempty"`
	Owner         string   `yaml:"owner,omitempty" json:"owner,omitempty"`
	Endpoint      string   `yaml:"endpoint,omitempty" json:"endpoint,omitempty"`
	Transport     string   `yaml:"transport,omitempty" json:"transport,omitempty"`
	Auth          string   `yaml:"auth,omitempty" json:"auth,omitempty"`
	NativeProduct bool     `yaml:"nativeProduct,omitempty" json:"nativeProduct,omitempty"`
	Capabilities  []string `yaml:"capabilities,omitempty" json:"capabilities,omitempty"`
}

type ApplicationDef

type ApplicationDef struct {
	Role                  string                                  `yaml:"role" json:"role"`
	DefaultTool           string                                  `yaml:"defaultTool,omitempty" json:"defaultTool,omitempty"`
	Alternatives          []string                                `yaml:"alternatives,omitempty" json:"alternatives,omitempty"`
	Description           string                                  `yaml:"description,omitempty" json:"description,omitempty"`
	Package               string                                  `yaml:"package,omitempty" json:"package,omitempty"`
	DefaultRuntimeProfile string                                  `yaml:"defaultRuntimeProfile,omitempty" json:"defaultRuntimeProfile,omitempty"`
	RuntimeProfiles       map[string]ApplicationRuntimeProfileDef `yaml:"runtimeProfiles,omitempty" json:"runtimeProfiles,omitempty"`
	Connectors            map[string]ApplicationConnectorDef      `yaml:"connectors,omitempty" json:"connectors,omitempty"`
	ProductAPIs           map[string]ApplicationProductAPIDef     `yaml:"productApis,omitempty" json:"productApis,omitempty"`
	RIL                   *ApplicationRILDef                      `yaml:"ril,omitempty" json:"ril,omitempty"`
}

ApplicationDef is a user-facing application category (photos, media, ...). Lives under stackkit.yaml `application:` key (canonical L3 layer per ADR-0012). Pre-2026-04 this was named UseCaseDef under `useCases:` — see migration 000084.

type ApplicationProductAPIDef

type ApplicationProductAPIDef struct {
	Protocol string `yaml:"protocol,omitempty" json:"protocol,omitempty"`
	BasePath string `yaml:"basePath,omitempty" json:"basePath,omitempty"`
	Auth     string `yaml:"auth,omitempty" json:"auth,omitempty"`
	Purpose  string `yaml:"purpose,omitempty" json:"purpose,omitempty"`
}

type ApplicationRILCapabilityDef

type ApplicationRILCapabilityDef struct {
	Mode             string `yaml:"mode,omitempty" json:"mode,omitempty"`
	Authority        string `yaml:"authority,omitempty" json:"authority,omitempty"`
	Source           string `yaml:"source,omitempty" json:"source,omitempty"`
	RequiresApproval bool   `yaml:"requiresApproval,omitempty" json:"requiresApproval,omitempty"`
	Evidence         string `yaml:"evidence,omitempty" json:"evidence,omitempty"`
}

type ApplicationRILDef

type ApplicationRILDef struct {
	Capabilities map[string]ApplicationRILCapabilityDef `yaml:"capabilities,omitempty" json:"capabilities,omitempty"`
}

type ApplicationRuntimeProfileDef

type ApplicationRuntimeProfileDef struct {
	DisplayName               string   `yaml:"displayName,omitempty" json:"displayName,omitempty"`
	Description               string   `yaml:"description,omitempty" json:"description,omitempty"`
	Realization               string   `yaml:"realization,omitempty" json:"realization,omitempty"`
	PlacementModes            []string `yaml:"placementModes,omitempty" json:"placementModes,omitempty"`
	Contexts                  []string `yaml:"contexts,omitempty" json:"contexts,omitempty"`
	ManagedServerlessEligible bool     `yaml:"managedServerlessEligible,omitempty" json:"managedServerlessEligible,omitempty"`
	RequiresControlPlane      bool     `yaml:"requiresControlPlane,omitempty" json:"requiresControlPlane,omitempty"`
	RequiresLocalBridge       bool     `yaml:"requiresLocalBridge,omitempty" json:"requiresLocalBridge,omitempty"`
	Notes                     []string `yaml:"notes,omitempty" json:"notes,omitempty"`
}

type ChangelogEntry

type ChangelogEntry struct {
	Version string   `yaml:"version" json:"version"`
	Date    string   `yaml:"date,omitempty" json:"date,omitempty"`
	Changes []string `yaml:"changes,omitempty" json:"changes,omitempty"`
}

ChangelogEntry mirrors a YAML changelog item.

type ComputeTierDef

type ComputeTierDef struct {
	Requirements       ResourceRequirements   `yaml:"requirements,omitempty" json:"requirements,omitempty"`
	AdditionalServices []string               `yaml:"additionalServices,omitempty" json:"additionalServices,omitempty"`
	ServiceOverrides   map[string]interface{} `yaml:"serviceOverrides,omitempty" json:"serviceOverrides,omitempty"`
	PaasOverride       string                 `yaml:"paasOverride,omitempty" json:"paasOverride,omitempty"`
}

ComputeTierDef is a tier sizing entry (low/standard/high).

type FieldDifference

type FieldDifference struct {
	Path          string      `json:"path"`
	Severity      string      `json:"severity"` // "critical" | "cosmetic"
	Original      interface{} `json:"original,omitempty"`
	Reconstructed interface{} `json:"reconstructed,omitempty"`
	Note          string      `json:"note,omitempty"`
}

FieldDifference is a single field-level diff entry.

func Diff

func Diff(a, b KitDefinition) []FieldDifference

Diff produces a list of FieldDifference entries between two KitDefinition values. Tracks the most relevant top-level + nested field paths for roundtrip validation.

type FoundationDef

type FoundationDef struct {
	Role         string   `yaml:"role" json:"role"`
	Alternatives []string `yaml:"alternatives,omitempty" json:"alternatives,omitempty"`
	Description  string   `yaml:"description,omitempty" json:"description,omitempty"`
}

FoundationDef is a foundation-layer service slot.

type KitDefinition

type KitDefinition struct {
	APIVersion   string                    `yaml:"apiVersion,omitempty" json:"apiVersion,omitempty"`
	Kind         string                    `yaml:"kind,omitempty" json:"kind,omitempty"`
	Metadata     KitMetadata               `yaml:"metadata" json:"metadata"`
	SupportedOS  []string                  `yaml:"supportedOS,omitempty" json:"supportedOS,omitempty"`
	Requirements map[string]interface{}    `yaml:"requirements,omitempty" json:"requirements,omitempty"`
	Modes        map[string]ModeDef        `yaml:"modes,omitempty" json:"modes,omitempty"`
	AutoSelect   map[string]interface{}    `yaml:"autoSelect,omitempty" json:"autoSelect,omitempty"`
	Application  map[string]ApplicationDef `yaml:"application,omitempty" json:"application,omitempty"`
	Foundation   map[string]FoundationDef  `yaml:"foundation,omitempty" json:"foundation,omitempty"`
	Platform     PlatformField             `yaml:"platform,omitempty" json:"platform,omitempty"`
	Features     map[string]bool           `yaml:"features,omitempty" json:"features,omitempty"`
	ComputeTiers map[string]ComputeTierDef `yaml:"computeTiers,omitempty" json:"computeTiers,omitempty"`
	Outputs      map[string]interface{}    `yaml:"outputs,omitempty" json:"outputs,omitempty"`
	Changelog    []ChangelogEntry          `yaml:"changelog,omitempty" json:"changelog,omitempty"`

	// Multi-node kit fields
	NodeTypes map[string]NodeTypeDef `yaml:"nodeTypes,omitempty" json:"nodeTypes,omitempty"`
	Addons    AddonsDef              `yaml:"addons,omitempty" json:"addons,omitempty"`
	Identity  map[string]interface{} `yaml:"identity,omitempty" json:"identity,omitempty"`
	Pattern   map[string]interface{} `yaml:"pattern,omitempty" json:"pattern,omitempty"`
	PaaS      map[string]interface{} `yaml:"paas,omitempty" json:"paas,omitempty"`
	Secrets   map[string]interface{} `yaml:"secrets,omitempty" json:"secrets,omitempty"`

	// Cluster-oriented kit fields
	Swarm    map[string]interface{} `yaml:"swarm,omitempty" json:"swarm,omitempty"`
	Services []ServiceSpecDef       `yaml:"services,omitempty" json:"services,omitempty"`
	Extends  string                 `yaml:"extends,omitempty" json:"extends,omitempty"`

	// Common optional
	Architecture    string   `yaml:"architecture,omitempty" json:"architecture,omitempty"`
	TunnelOptions   []string `yaml:"tunnelOptions,omitempty" json:"tunnelOptions,omitempty"`
	SecretsProvider string   `yaml:"-" json:"secretsProvider,omitempty"`

	// Publication fields materialized by the private Git/CUE publisher.
	CueSourcePath string `yaml:"-" json:"cueSourcePath,omitempty"`
	ContractHash  string `yaml:"-" json:"contractHash,omitempty"`
}

KitDefinition is the canonical in-process shape for a Git-owned Kit source.

func Import

func Import(yamlBytes []byte) (KitDefinition, error)

Import parses stackkit.yaml bytes into a KitDefinition.

Two-pass approach:

  1. yaml.Unmarshal into KitDefinition struct (typed sections).
  2. Re-parse as generic map to preserve unknown keys (Outputs, Pattern etc. that the struct surfaces as map[string]interface{}).

type KitMetadata

type KitMetadata = models.KitMetadata

KitMetadata is a source-compatible alias to the one concrete Go schema.

type ModeDef

type ModeDef struct {
	Description    string                   `yaml:"description,omitempty" json:"description,omitempty"`
	TemplateDir    string                   `yaml:"templateDir,omitempty" json:"templateDir,omitempty"`
	Engine         string                   `yaml:"engine,omitempty" json:"engine,omitempty"`
	Recommended    bool                     `yaml:"recommended,omitempty" json:"recommended,omitempty"`
	Features       []string                 `yaml:"features,omitempty" json:"features,omitempty"`
	Requires       []string                 `yaml:"requires,omitempty" json:"requires,omitempty"`
	RecommendedFor []string                 `yaml:"recommended_for,omitempty" json:"recommended_for,omitempty"`
	Stacks         []map[string]interface{} `yaml:"stacks,omitempty" json:"stacks,omitempty"`
}

ModeDef captures an install/lifecycle mode such as bare, bootstrapped, or advanced.

type NodeTypeDef

type NodeTypeDef struct {
	Description  string                 `yaml:"description,omitempty" json:"description,omitempty"`
	Access       string                 `yaml:"access,omitempty" json:"access,omitempty"`
	Role         string                 `yaml:"role,omitempty" json:"role,omitempty"`
	Requirements map[string]interface{} `yaml:"requirements,omitempty" json:"requirements,omitempty"`
	Providers    []string               `yaml:"providers,omitempty" json:"providers,omitempty"`
}

NodeTypeDef describes local/cloud node roles in multi-node kit definitions.

type PlatformDef

type PlatformDef struct {
	Role         string   `yaml:"role" json:"role"`
	DefaultTool  string   `yaml:"defaultTool,omitempty" json:"defaultTool,omitempty"`
	Alternatives []string `yaml:"alternatives,omitempty" json:"alternatives,omitempty"`
	Description  string   `yaml:"description,omitempty" json:"description,omitempty"`
}

PlatformDef is a platform-layer service slot.

type PlatformField

type PlatformField struct {
	// AsString holds the scalar form, e.g. "docker".
	AsString string
	// AsMap holds the structured form (basement-kit).
	AsMap map[string]PlatformDef
}

PlatformField is a polymorphic yaml `platform:` value.

In basement-kit it is a map of platform service slots:

platform:
  traefik: { role: default }
  paas: { role: optional, defaultTool: coolify }

In future kit definitions it may be represented as a single string:

platform: docker

We keep both forms reachable.

func (PlatformField) IsEmpty

func (p PlatformField) IsEmpty() bool

IsEmpty reports whether the field carries no data.

func (PlatformField) MarshalJSON

func (p PlatformField) MarshalJSON() ([]byte, error)

MarshalJSON keeps the symmetry for kit-import POST body.

func (PlatformField) MarshalYAML

func (p PlatformField) MarshalYAML() (interface{}, error)

MarshalYAML emits the string form when set, otherwise the map form, otherwise nothing.

func (*PlatformField) UnmarshalJSON

func (p *PlatformField) UnmarshalJSON(b []byte) error

UnmarshalJSON accepts string-or-map for kit-export round-trip.

func (*PlatformField) UnmarshalYAML

func (p *PlatformField) UnmarshalYAML(node *yaml.Node) error

UnmarshalYAML accepts both yaml shapes.

type ResourceRequirements

type ResourceRequirements struct {
	CPU      int    `yaml:"cpu,omitempty" json:"cpu,omitempty"`
	Memory   int    `yaml:"memory,omitempty" json:"memory,omitempty"`
	Disk     int    `yaml:"disk,omitempty" json:"disk,omitempty"`
	DiskType string `yaml:"diskType,omitempty" json:"diskType,omitempty"`
	// Multi-node
	ManagerNodes int `yaml:"managerNodes,omitempty" json:"managerNodes,omitempty"`
	WorkerNodes  int `yaml:"workerNodes,omitempty" json:"workerNodes,omitempty"`
	Nodes        int `yaml:"nodes,omitempty" json:"nodes,omitempty"`
}

ResourceRequirements captures cpu/memory/disk + optional disk type.

type ReverseMapping

type ReverseMapping struct {
	Section SectionKind
	Key     string
}

ReverseMapping records the original section + key that produced a given service-group slug. Used by export to put selections back into the right stackkit.yaml section.

func GroupReverseMappings

func GroupReverseMappings(groupSlug string) []ReverseMapping

GroupReverseMappings returns the section/key pairs that map to a given service-group slug. Some groups (e.g. "forward-auth") have multiple sources (foundation.login-gateway + platform.tinyauth) — both are returned.

type RoundTripReport

type RoundTripReport struct {
	Slug              string            `json:"slug"`
	OriginalHash      string            `json:"originalHash"`
	ReconstructedHash string            `json:"reconstructedHash"`
	HashesEqual       bool              `json:"hashesEqual"`
	Differences       []FieldDifference `json:"differences,omitempty"`
	CosmeticOnly      bool              `json:"cosmeticOnly"`
	Formats           []string          `json:"formats"`
}

RoundTripReport captures the structural diff between the original kit definition and the reconstructed one.

func LocalRoundTrip

func LocalRoundTrip(yamlBytes []byte) (RoundTripReport, error)

LocalRoundTrip runs the YAML-only roundtrip cycle in memory:

  1. Import original yaml -> KitDefinition A
  2. Export A -> reconstructed yaml
  3. Import reconstructed yaml -> KitDefinition B
  4. Compare A vs B as structs (cosmetic yaml differences ignored)
  5. Compute hashes; match indicates lossless roundtrip

This is the cheap, no-API check that ships with `stackkit kit roundtrip` and runs in unit tests. The live API counterpart lives in client.go + kit_roundtrip_live_test.go.

type SectionKind

type SectionKind string

SectionKind identifies which yaml section a service-group belongs to.

const (
	SectionApplication SectionKind = "application"
	SectionFoundation  SectionKind = "foundation"
	SectionPlatform    SectionKind = "platform"
)

func PreferredSection

func PreferredSection(groupSlug string) (SectionKind, string, bool)

PreferredSection picks the canonical section for a group when multiple sources exist. Rule: foundation > platform > application. Within the same section, we prefer the SHORTER key, then lexicographically earlier — this keeps `login-gateway` (the documented canonical) winning over `tinyauth` (the legacy alias) for forward-auth, deterministically.

Migration 000086 (P1-2 fix): login-gateway moved from foundation to platform per ARCHITECTURE_V6 §4. Both login-gateway and tinyauth are now in platform; the deterministic-within-section rule keeps the canonical pair stable.

type ServiceSpecDef

type ServiceSpecDef struct {
	Name        string                 `yaml:"name" json:"name"`
	Required    bool                   `yaml:"required,omitempty" json:"required,omitempty"`
	Description string                 `yaml:"description,omitempty" json:"description,omitempty"`
	Status      string                 `yaml:"status,omitempty" json:"status,omitempty"`
	Replicas    *int                   `yaml:"replicas,omitempty" json:"replicas,omitempty"`
	SwarmMode   bool                   `yaml:"swarmMode,omitempty" json:"swarmMode,omitempty"`
	Deploy      map[string]interface{} `yaml:"deploy,omitempty" json:"deploy,omitempty"`
}

ServiceSpecDef declares deployment overrides per service.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL