platformimport

package
v0.8.0 Latest Latest
Warning

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

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

Documentation

Overview

Package platformimport reads apps from another self-hosted platform (read-only) into a neutral model and maps it to this platform's resources. The source credential is used in memory only.

Index

Constants

View Source
const (
	AllowPrivateEnv  = "APP_IMPORT_ALLOW_PRIVATE_NETWORKS"
	AllowLoopbackEnv = "APP_IMPORT_ALLOW_LOOPBACK"
)

Environment variables that must be set before a request may opt in to private or loopback source addresses. Both the env var and the request field are required, so a leaked API token alone cannot aim the control plane at the internal network.

View Source
const (
	LabelSourceID       = "import/source-id"
	LabelSourcePlatform = "import/source-platform"
	LabelSourceName     = "import/source-name"
	// LabelSession ties a staged app to the guided import session that created it.
	LabelSession = "import/session"
)

Labels stamped on every imported resource. The source-id label is what makes a re-run idempotent and lets an operator find imports to delete.

View Source
const (
	StatusMapped         = "mapped"
	StatusNeedsAttention = "needs-attention"
	StatusUnsupported    = "unsupported"
	StatusAlready        = "already-imported"
	StatusSkipped        = "skipped"
	StatusCreated        = "created"
	StatusFailed         = "failed"
)

Item statuses in a Report.

View Source
const (
	CollisionSuffix = "suffix"
	CollisionSkip   = "skip"
)

Collision modes for a target name that is already taken.

View Source
const DataNote = "" /* 171-byte string literal not displayed */

DataNote is added to every report that contains databases.

View Source
const (

	// MaxPages bounds every paginated or fan-out walk.
	MaxPages = 200
)

Variables

View Source
var ErrBlockedAddress = errors.New("platformimport: source address is not allowed")

ErrBlockedAddress is returned when the source URL resolves to an address the network policy forbids.

Functions

func LooksSecret

func LooksSecret(key string) bool

LooksSecret reports whether an env var name suggests a secret value.

func SanitizeName

func SanitizeName(s string) string

SanitizeName turns a source name into a valid resource name.

Types

type APIError

type APIError struct {
	Status int
	Body   string
}

APIError is a non-2xx reply from the source.

func (*APIError) Error

func (e *APIError) Error() string

type App

type App struct {
	SourceID    string
	Name        string
	Project     string
	Environment string
	// Server names the source host the app runs on, empty when unreported.
	Server string
	// BuildPack is the source's own build method name, unmapped.
	BuildPack string
	// PrivateRepo is true when the source needs credentials to clone.
	PrivateRepo bool
	Kind        SourceKind
	Image       string
	// ImageID is the source host's local image ID, set by snapshot sources.
	ImageID string
	// SourceContainer is the running container's ID on the source host, set by live Docker sources.
	SourceContainer string
	// HostBuilt marks an image built on the source host and absent from any registry.
	HostBuilt   bool
	GitURL      string
	GitBranch   string
	BuildMethod string
	BuildPath   string
	Port        int
	Env         []Env
	Domains     []string
	Volumes     []Volume
	Replicas    int
	Health      *HealthCheck
	Crons       []Cron
	MemoryBytes int64
	NanoCPUs    int64
	Notes       []Note
}

App is one application in the neutral model.

type AppPlan

type AppPlan struct {
	SourceID    string            `json:"source_id"`
	SourceName  string            `json:"source_name"`
	Name        string            `json:"name"`
	Image       string            `json:"image"`
	Port        int               `json:"port"`
	Env         map[string]string `json:"env,omitempty"`
	Secrets     map[string]string `json:"-"`
	Domains     []string          `json:"domains,omitempty"`
	Volumes     []VolumePlan      `json:"volumes,omitempty"`
	Replicas    int               `json:"replicas"`
	Health      *HealthPlan       `json:"health,omitempty"`
	MemoryBytes int64             `json:"memory_bytes,omitempty"`
	NanoCPUs    int64             `json:"nano_cpus,omitempty"`
	Labels      map[string]string `json:"labels"`
	Project     string            `json:"project,omitempty"`
	GitURL      string            `json:"git_url,omitempty"`
	GitBranch   string            `json:"git_branch,omitempty"`
	BuildMethod string            `json:"build_method,omitempty"`
	BuildPath   string            `json:"build_path,omitempty"`
}

AppPlan is one app create request. Secrets holds plaintext and is never serialized.

type Applier

type Applier interface {
	CreateApp(ctx context.Context, p AppPlan) (warnings []string, err error)
	CreateDatabase(ctx context.Context, p DatabasePlan) (warnings []string, err error)
}

Applier creates resources on this platform. Implementations must be safe to call again after a partial failure.

type CapRoverSource

type CapRoverSource struct {
	// contains filtered or unexported fields
}

CapRoverSource reads a CapRover instance. The login POST is the only non-GET call it makes.

func NewCapRover

func NewCapRover(baseURL, password string, o ClientOptions) (*CapRoverSource, error)

NewCapRover builds a CapRover source. The password is exchanged for a session token in memory and never stored.

func (*CapRoverSource) Discover

func (s *CapRoverSource) Discover(ctx context.Context) (*Discovery, error)

Discover logs in and reads every app definition.

type ClientOptions

type ClientOptions struct {
	Policy   NetworkPolicy
	Insecure bool
}

ClientOptions configure the source HTTP client.

type ComposeSource

type ComposeSource struct {
	Data []byte
}

ComposeSource maps a plain compose file, one app per service.

func (ComposeSource) Discover

func (s ComposeSource) Discover(_ context.Context) (*Discovery, error)

Discover parses the compose file. Services with build: blocks are reported as unsupported since there is no source tree to build from.

type CoolifySource

type CoolifySource struct {
	// contains filtered or unexported fields
}

CoolifySource reads a Coolify instance through its bearer-token API v1.

func NewCoolify

func NewCoolify(baseURL, token string, o ClientOptions) (*CoolifySource, error)

NewCoolify builds a Coolify source. The token is kept in memory only.

func (*CoolifySource) Discover

func (c *CoolifySource) Discover(ctx context.Context) (*Discovery, error)

Discover walks projects, environments, applications, databases and services.

type Cron

type Cron struct {
	Name     string
	Schedule string
	Command  string
}

Cron is a scheduled command.

type Database

type Database struct {
	SourceID string
	Name     string
	Project  string
	Engine   string
	Version  string
	// Environment and InternalHost are set by sources that give each
	// database an in-network hostname apps connect to.
	Environment  string
	InternalHost string
}

Database is a managed database in the source platform.

type DatabasePlan

type DatabasePlan struct {
	SourceID   string `json:"source_id"`
	SourceName string `json:"source_name"`
	Name       string `json:"name"`
	Engine     string `json:"engine"`
	Version    string `json:"version"`
	Project    string `json:"project,omitempty"`
}

DatabasePlan is one managed database create request (empty, no data).

type Discovery

type Discovery struct {
	Platform    Platform
	Projects    []string
	Apps        []App
	Databases   []Database
	Unsupported []Unsupported
}

Discovery is everything read from a source.

type DockerSSHSource

type DockerSSHSource struct {
	Reader InspectReader
}

DockerSSHSource reads a host's containers through a read-only Docker socket tunnel and maps them like a pasted docker inspect snapshot. Env comes from each container's runtime config; the old platform's own stored config (Coolify's database, CapRover's /captain/data, Dokku's /home/dokku) is not read.

func (DockerSSHSource) Discover

func (s DockerSSHSource) Discover(ctx context.Context) (*Discovery, error)

Discover reads every container over the tunnel and parses the result.

type DockerSource

type DockerSource struct {
	Data []byte
}

DockerSource maps a `docker inspect` snapshot of every container on a host into the neutral model. It is read-only and needs no credential for the platform that launched the containers, so it works when only the Docker host is reachable (no Coolify token, no Dokploy key).

func (DockerSource) Discover

func (s DockerSource) Discover(_ context.Context) (*Discovery, error)

Discover parses the snapshot, a JSON array as printed by `docker inspect $(docker ps -aq)`.

type DokkuEnvSource

type DokkuEnvSource struct {
	AppName string
	Data    string
}

DokkuEnvSource maps one Dokku app from a `dokku config:export` style dump (KEY=VALUE lines). It never contacts a Dokku host.

func (DokkuEnvSource) Discover

func (s DokkuEnvSource) Discover(_ context.Context) (*Discovery, error)

Discover returns one app with the dumped variables. Dokku's own generated variables (DOKKU_*, GIT_REV) are dropped.

type DokploySource

type DokploySource struct {
	// contains filtered or unexported fields
}

DokploySource reads a Dokploy instance through its x-api-key API.

func NewDokploy

func NewDokploy(baseURL, apiKey string, o ClientOptions) (*DokploySource, error)

NewDokploy builds a Dokploy source. The API key is kept in memory only.

func (*DokploySource) Discover

func (s *DokploySource) Discover(ctx context.Context) (*Discovery, error)

Discover lists projects (which embed their resources) and reads each app.

type Env

type Env struct {
	Key    string
	Value  string
	Secret bool
}

Env is one environment variable. Secret is true when the source marked it secret or the key looks like one.

type HealthCheck

type HealthCheck struct {
	Path            string
	IntervalSeconds int
	TimeoutSeconds  int
	Retries         int
}

HealthCheck is an HTTP probe.

type HealthPlan

type HealthPlan struct {
	Path            string
	IntervalSeconds int
	TimeoutSeconds  int
	Failures        int
}

HealthPlan is an HTTP readiness probe.

type InspectReader

type InspectReader interface {
	InspectAll(ctx context.Context) ([]byte, error)
}

InspectReader returns the inspect JSON of every container on a host as one array.

type Item

type Item struct {
	Kind       string   `json:"kind"`
	SourceID   string   `json:"source_id"`
	SourceName string   `json:"source_name"`
	Target     string   `json:"target,omitempty"`
	Status     string   `json:"status"`
	Reasons    []string `json:"reasons,omitempty"`
	Manual     []string `json:"manual,omitempty"`
}

Item is one report row.

type NetworkPolicy

type NetworkPolicy struct {
	AllowPrivate  bool
	AllowLoopback bool
}

NetworkPolicy decides which destinations the source client may dial. Cloud metadata and link-local addresses are never allowed.

func (NetworkPolicy) Check

func (p NetworkPolicy) Check(addr netip.Addr) error

Check reports whether addr may be dialed under the policy.

type Note

type Note struct {
	Reason string
	Manual string
}

Note is a per-item caveat found while reading the source.

type Plan

type Plan struct {
	Apps      []AppPlan
	Databases []DatabasePlan
	Report    Report
}

Plan is the mapped result of a Discovery.

func BuildPlan

func BuildPlan(d *Discovery, o PlanOptions) *Plan

BuildPlan maps a Discovery onto create requests and a Report.

type PlanOptions

type PlanOptions struct {
	// Only restricts the plan to these source ids or source names. Empty means all.
	Only []string
	// Collision is CollisionSuffix (default) or CollisionSkip.
	Collision string
	// ExistingApps maps an import label value (platform:sourceID) to the
	// app already created for it. TakenApps is every app name in use.
	ExistingApps map[string]string
	TakenApps    map[string]bool
	// ExistingDatabases maps a database name to "engine:version".
	ExistingDatabases map[string]string
}

PlanOptions steer mapping.

type Platform

type Platform string

Platform identifies a supported source.

const (
	Coolify  Platform = "coolify"
	Dokploy  Platform = "dokploy"
	CapRover Platform = "caprover"
	Compose  Platform = "compose"
	Dokku    Platform = "dokku"
	// Docker is a docker inspect snapshot of one host, no platform API.
	Docker Platform = "docker"
	// DockerSSH reads one host's Docker socket through an SSH login, no platform API.
	DockerSSH Platform = "docker-ssh"
)

Supported source platforms.

func ParsePlatform

func ParsePlatform(s string) (Platform, error)

ParsePlatform validates a platform name: a live source or a pasted file.

type Report

type Report struct {
	Platform Platform       `json:"platform"`
	Items    []Item         `json:"items"`
	Counts   map[string]int `json:"counts"`
	Notes    []string       `json:"notes,omitempty"`
}

Report is the per-item outcome of a discover, plan or apply.

func Apply

func Apply(ctx context.Context, plan *Plan, ap Applier) Report

Apply creates every planned resource, continuing past individual failures so a re-run (which skips what already exists) can finish the rest. It returns the plan's report with created and failed statuses.

type Source

type Source interface {
	Discover(ctx context.Context) (*Discovery, error)
}

Source discovers the neutral model from one source platform.

func NewSource

func NewSource(platform Platform, baseURL, token string, o ClientOptions) (Source, error)

NewSource builds a live source adapter for a platform. The token is the Coolify bearer token, Dokploy API key or CapRover password.

type SourceKind

type SourceKind string

SourceKind says where an app's code comes from.

const (
	SourceImage   SourceKind = "image"
	SourceGit     SourceKind = "git"
	SourceUnknown SourceKind = "unknown"
)

Where an app comes from.

type Unsupported

type Unsupported struct {
	Kind     string
	SourceID string
	Name     string
	Reason   string
	Manual   string
	// Context the source reported about the unsupported item, for display.
	Project     string
	Environment string
	Server      string
	Source      string
	Domains     []string
	Port        int
}

Unsupported is something that cannot be imported.

type Volume

type Volume struct {
	Name          string
	HostPath      string
	ContainerPath string
	ReadOnly      bool
	// SizeBytes is 0 when the source API does not report volume sizes.
	SizeBytes int64
}

Volume is a persistent mount.

type VolumePlan

type VolumePlan struct {
	Name          string
	HostPath      string
	ContainerPath string
	ReadOnly      bool
}

VolumePlan is a named volume or bind mount.

Directories

Path Synopsis
Package fakecoolify is a read-only stand-in for the Coolify v4 REST API, shaped from the documented responses the importer consumes.
Package fakecoolify is a read-only stand-in for the Coolify v4 REST API, shaped from the documented responses the importer consumes.
cmd/fakecoolify command
Command fakecoolify serves the read-only fake Coolify API for local runs of the app import flow.
Command fakecoolify serves the read-only fake Coolify API for local runs of the app import flow.

Jump to

Keyboard shortcuts

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