Documentation
¶
Overview ¶
Package helm generates Helm charts from Deployah specs and drives install, upgrade, list, and delete operations against a cluster.
PrepareChart renders templates and values for an environment into a caller-supplied ChartCache. Client wraps Helm v4 actions with Deployah-specific release naming, labels, and a per-client ChartCache.
Index ¶
- Constants
- Variables
- func GenerateReleaseName(projectName, environmentName string) string
- func MapSpecToChartValues(m *spec.Spec, desiredEnvironment string, resolved *spec.ResolvedSpec) (map[string]any, error)
- func PrepareChart(ctx context.Context, manifest *spec.Spec, desiredEnvironment string, ...) (string, error)
- type ChartCache
- type ChartData
- type Client
- func (c *Client) DeleteRelease(ctx context.Context, project, environment string, wait bool) error
- func (c *Client) GetRelease(ctx context.Context, project, environment string) (*v1.Release, error)
- func (c *Client) GetReleaseHistory(ctx context.Context, project, environment string) ([]*v1.Release, error)
- func (c *Client) InstallApp(ctx context.Context, manifest *spec.Spec, environment string, dryRun bool, ...) error
- func (c *Client) IsReachable() error
- func (c *Client) ListReleases(ctx context.Context, selector labels.Selector) ([]*v1.Release, error)
- func (c *Client) Namespace() string
- func (c *Client) RenderManifests(ctx context.Context, manifest *spec.Spec, environment string, ...) (result *render.RenderResult, cleanup func(), err error)
- func (c *Client) RenderOffline(ctx context.Context, manifest *spec.Spec, environment string, ...) (result *render.RenderResult, cleanup func(), err error)
- func (c *Client) RollbackRelease(ctx context.Context, releaseName string, revision int, timeout time.Duration) error
- type Option
- func WithChartCache(cache *ChartCache) Option
- func WithDebug(keep bool) Option
- func WithExtraKubeconfigPaths(paths ...string) Option
- func WithKubeContext(kubeContext string) Option
- func WithKubeconfig(kubeconfig string) Option
- func WithNamespace(namespace string) Option
- func WithStorageDriver(driver string) Option
- func WithTimeout(timeout time.Duration) Option
Constants ¶
const ( // ChartNameTemplate is the template for generated chart names ChartNameTemplate = "%s-%s" // ReleaseNameTemplate is the template for Helm release names ReleaseNameTemplate = "%s-%s" // TempChartPrefix is the prefix for temporary chart directories TempChartPrefix = "deployah-chart-" // ChartYamlTemplate is the template file name for Chart.yaml ChartYamlTemplate = "Chart.yaml.gotmpl" // ValuesYamlFile is the name of the values file ValuesYamlFile = "values.yaml" )
Chart and Template Constants
Variables ¶
var ( // ErrClusterUnreachable is returned when the Kubernetes cluster cannot be reached. ErrClusterUnreachable = errors.New("kubernetes cluster unreachable") // ErrReleaseNotFound is returned when a Helm release does not exist. ErrReleaseNotFound = errors.New("release not found") // ErrReleaseAlreadyExists is returned when a Helm release already exists. // // Produced by [Client.wrapHelmError] from typed Helm/Kubernetes errors // when available, otherwise from Helm's plain "already exists" message. // Callers may match with [errors.Is]. ErrReleaseAlreadyExists = errors.New("release already exists") // ErrReleasePending is returned when a Helm release has an operation in progress. // // Only [Client.InstallApp] produces this sentinel, via a typed check of the // newest revision's pending status (Status.IsPending) before upgrade. // [Client.wrapHelmError] does not classify Helm's plain pending messages, so // other action paths (and a rare race after the pre-check) surface those as // generic helm failures. Callers may match with [errors.Is]. ErrReleasePending = errors.New("another operation is in progress") )
var ChartTemplateFS embed.FS
ChartTemplateFS embeds the chart directory. Underscore-prefixed templates were renamed so directory embedding includes them without explicit listing.
Functions ¶
func GenerateReleaseName ¶
GenerateReleaseName returns the Helm release name for project and environment. Format: PROJECT_NAME-ENVIRONMENT_NAME.
func MapSpecToChartValues ¶ added in v0.3.0
func MapSpecToChartValues(m *spec.Spec, desiredEnvironment string, resolved *spec.ResolvedSpec) (map[string]any, error)
MapSpecToChartValues converts a spec into Helm chart values for the given environment (resolved, if non-nil, supplies FQDN/TLS) and writes a deployah.resolved block so the hostname guard can compare across deploys.
func PrepareChart ¶
func PrepareChart(ctx context.Context, manifest *spec.Spec, desiredEnvironment string, resolved *spec.ResolvedSpec, cache *ChartCache) (string, error)
PrepareChart expands the embedded chart into a temporary directory, rendering .gotmpl files with Go templates and Sprig functions, and returns the prepared chart root directory. Identical charts are reused via cache.
cache must be non-nil. If ctx is already canceled or past its deadline, PrepareChart returns context.Canceled or context.DeadlineExceeded immediately; chart expansion itself is not interrupted mid-flight.
When resolved is non-nil, the cache key hashes resolved (including spec.ResolvedSpec.Spec), not the separate manifest parameter. Callers must pass a manifest consistent with resolved.Spec: chart rendering still reads component names and project from manifest, so a mismatched pair could reuse a stale chart.
On a cache miss, every 10th entry may start a background goroutine that removes expired cache directories; that work outlives this call.
Errors: context.Canceled, context.DeadlineExceeded, or a wrapped error when cache is nil or chart generation fails.
Types ¶
type ChartCache ¶
type ChartCache struct {
// contains filtered or unexported fields
}
ChartCache stores prepared chart directories keyed by content hash. Each Client owns one instance (see NewClient and WithChartCache). There is no process-global cache. Methods are safe for concurrent use.
func NewChartCache ¶ added in v0.6.0
func NewChartCache(ttl time.Duration) *ChartCache
NewChartCache returns an empty chart cache with the given TTL. A non-positive ttl falls back to one hour.
func (*ChartCache) GenerateKey ¶ added in v0.6.0
func (c *ChartCache) GenerateKey(manifest *spec.Spec, environment string, resolved *spec.ResolvedSpec) (string, error)
GenerateKey creates a cache key from the resolved spec (or raw spec when resolved is nil), the target environment, and this cache's embedded chart template hash.
environment must be part of the key: PrepareChart bakes the environment-filtered component set and environment label into the cached chart's values.yaml, so rendering environment A then B for the same manifest must not reuse A's cached chart for B.
When resolved is non-nil it is hashed instead of the full raw spec: this covers only the target-environment subset and ensures platform file changes invalidate the cache. encoding/json sorts map keys deterministically since Go 1.12, so the serialization is stable.
type ChartData ¶
type ChartData struct {
// Chart holds metadata rendered into Chart.yaml.
Chart struct {
Name string
Description string
Version string
AppVersion string
}
// Values is the data map for values.yaml templating.
Values map[string]any
// ComponentNames are the sorted names of the component sub-charts
// created for this environment.
ComponentNames []string
// TaskNames are the sorted names of the task sub-charts created for this
// environment. Hook and scheduled tasks each get one.
TaskNames []string
}
ChartData holds values substituted in Helm chart templates.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client wraps Helm action configuration for Deployah operations.
func NewClient ¶
NewClient initializes Helm action configuration with functional options. Default storage driver is "secret" if not specified. Default timeout is 5 minutes if not specified. Each client gets its own ChartCache unless WithChartCache is set.
func (*Client) DeleteRelease ¶
DeleteRelease uninstalls the given release. When wait is false (the default) it returns right after hooks complete, matching vanilla `helm uninstall`. When wait is true it blocks until all resources are removed, via the legacy polling strategy with foreground cascade deletion -- StatusWatcherStrategy is avoided here because it can report cluster-scoped resources as Terminating forever after Kubernetes already deleted them (helm/helm#31766).
func (*Client) GetRelease ¶
GetRelease retrieves a release by project and environment.
func (*Client) GetReleaseHistory ¶
func (c *Client) GetReleaseHistory(ctx context.Context, project, environment string) ([]*v1.Release, error)
GetReleaseHistory returns the history of a specific release.
func (*Client) InstallApp ¶
func (c *Client) InstallApp(ctx context.Context, manifest *spec.Spec, environment string, dryRun bool, resolved *spec.ResolvedSpec, postRenderer postrenderer.PostRenderer) error
InstallApp installs or upgrades the app using the embedded chart, using resolved (if non-nil) for platform-resolved FQDN/TLS values. When dryRun is true, it renders client-side via Client.RenderManifests instead of touching the cluster. postRenderer, when non-nil, is applied to rendered manifests before they are installed or upgraded.
func (*Client) IsReachable ¶
IsReachable reports whether the configured Kubernetes cluster is reachable.
Also works around helm/helm#32183: Helm panics on a second IsReachable call after the first one fails (typed-nil cached in getKubeClient), so calling this once before InstallApp keeps InstallApp from ever hitting that second call against a poisoned client. Upstream merged the fix in https://github.com/helm/helm/pull/32184 (2026-06-18), but helm.sh/helm/v4 v4.2.3 still ships the buggy getKubeClient. Re-check getKubeClient on the next Helm bump; the pre-call can be removed once the pin includes the fix.
func (*Client) ListReleases ¶
ListReleases returns release details in the current namespace.
func (*Client) Namespace ¶ added in v0.5.0
Namespace returns the release namespace Helm will use for installs and offline renders (from WithNamespace, HELM_NAMESPACE, or the kubeconfig context default).
func (*Client) RenderManifests ¶ added in v0.4.0
func (c *Client) RenderManifests(ctx context.Context, manifest *spec.Spec, environment string, resolved *spec.ResolvedSpec, postRenderer postrenderer.PostRenderer) (result *render.RenderResult, cleanup func(), err error)
RenderManifests renders the chart via Helm's DryRunClient strategy, so hooks/templates see the same values, capabilities, and revision as a real apply. It mirrors InstallApp's install-vs-upgrade decision so the result compares 1:1 with what InstallApp would produce, but on an upgrade this means it also performs InstallApp's cluster-reachability check (skipped only for a fresh install).
Callers must invoke the returned cleanup func; ChartPath is not removed automatically so callers like deploy can reuse it for the real apply.
func (*Client) RenderOffline ¶ added in v0.4.0
func (c *Client) RenderOffline(ctx context.Context, manifest *spec.Spec, environment string, resolved *spec.ResolvedSpec, postRenderer postrenderer.PostRenderer) (result *render.RenderResult, cleanup func(), err error)
RenderOffline renders the chart for manifest/environment as a fresh install, without any Kubernetes API access: no reachability check and no release-history lookup. It is the engine behind `deployah plan --offline`. Because it never looks at release history, the result always describes a fresh install (IsUpgrade false, Revision 1) even when a release already exists, so it can't be diffed against a prior release like Client.RenderManifests can; use that instead when cluster access is fine.
type Option ¶
type Option func(*Client)
Option is a functional option for configuring the Helm client
func WithChartCache ¶ added in v0.6.0
func WithChartCache(cache *ChartCache) Option
WithChartCache sets the prepared-chart cache used by this client. cache must be non-nil; NewClient rejects a nil cache.
func WithExtraKubeconfigPaths ¶
WithExtraKubeconfigPaths appends additional kubeconfig file paths so their contexts are available alongside the default kubeconfig. This is ignored when WithKubeconfig is also set, because an explicit path takes full precedence and makes extra paths redundant.
func WithKubeContext ¶
WithKubeContext sets the Kubernetes context to use, overriding the kubeconfig's current context.
func WithKubeconfig ¶
WithKubeconfig sets the path to the kubeconfig file
func WithNamespace ¶
WithNamespace sets the Kubernetes namespace for Helm operations
func WithStorageDriver ¶
WithStorageDriver sets the Helm storage driver (secret, configmap, or memory)
func WithTimeout ¶
WithTimeout sets the default timeout for Helm operations