chartify

package module
v0.20.0 Latest Latest
Warning

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

Go to latest
Published: Apr 28, 2024 License: Apache-2.0 Imports: 22 Imported by: 2

README

chartify

chartify converts anything to a Helm chart and modifies a chart in-place so that you don't need to fork an upstream helm chart only for a few custom requirements.

chartify is a Go library that is primarily used by helmfile to let it convert Kuberntes resource YAMLs or kustomize into a helm chart, and apply various modifications to the resulting chart.

chartify is intended to be run immediately before running helm upgrade --install. For example, instead of forking a helm chart, you should be able to prepend a chartify step into your deployment job in your CD pipeline. chartify isn't intended to create a fork of a chart. The output of chartify is a helm chart that is pre-rendered with all the helm values provided to chartify.

CLI

Beyond it's usage with helmfile, it also provides a basic CLI application that can be run independently.

The simplest usage of the command is:

$ chartify $RELEASE $CHART -o $OUTPUT_DIR

See chartify -h or go run ./cmd/chartify -h for more information.

Documentation

Overview

Copyright 2015 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

See k8s.io/apimachinery/pkg/util/rand/rand.go

Index

Constants

View Source
const (
	// EnvVarTempDir is the name of the environment variable that
	// contains the path of the specific directory to be used for generating
	// temporary charts.
	EnvVarTempDir = "CHARTIFY_TEMPDIR"

	// EnvVarDebug is the name of environment variable that
	// is set to a non-empty string whenever the user wants to enable
	// debugging functionality.
	// Currently, the only functionality is to write a `${temporary_chart_name}.json`
	// file that contains all the parameters used to generate the random temporary chart name.
	EnvVarDebug = "CHARTIFY_DEBUG"
)

Variables

View Source
var (
	ContentDirs = []string{"templates", "charts", "crds"}
)

Functions

func CopyFile

func CopyFile(src, dst string) error

CopyFile copies a single file from src to dst

func ExtractFilesFromChartTGZ

func ExtractFilesFromChartTGZ(tgzReader io.Reader, dir string) (string, error)

func ExtractFilesFromTGZ

func ExtractFilesFromTGZ(tgzReader io.Reader, dir string) error

func FindSemVerInfo

func FindSemVerInfo(version string) (string, error)

func GenerateID

func GenerateID(release, chart string, opts *ChartifyOpts) (string, error)

func HashObject

func HashObject(obj interface{}) (string, error)

func RunCommand

func RunCommand(cmd string, args []string, dir string, stdout, stderr io.Writer, env map[string]string) error

func SafeEncodeString

func SafeEncodeString(s string) string

SafeEncodeString encodes s using the same characters as rand.String. This reduces the chances of bad words and ensures that strings generated from hash functions appear consistent throughout the API.

Types

type ChartDependency

type ChartDependency struct {
	Alias   string
	Chart   string
	Version string
}

type ChartifyOption

type ChartifyOption interface {
	SetChartifyOption(opts *ChartifyOpts) error
}

func WithChartifyOpts

func WithChartifyOpts(opts *ChartifyOpts) ChartifyOption

type ChartifyOpts

type ChartifyOpts struct {
	// ID is the ID of the temporary chart being generated.
	// The ID is used in e.g. the directory name of the temporary local chart
	// genereated by chartify.
	// If it's empty, chartify generates one from the release namd, the chart name, and the hash of chartify options.
	ID string

	// Debug when set to true passes `--debug` flag to `helm` in order to enable debug logging
	Debug bool

	// ValuesFiles are a list of Helm chart values files
	ValuesFiles []string

	// DEPRECATED: Use SetFlags instead.
	// SetValues is a list of adhoc Helm chart values being passed via helm's `--set` flags
	SetValues []string

	// SetFlags is the list of set flags like --set k=v, --set-file k=path, --set-string k=str
	// used while rendering the chart.
	SetFlags []string

	// Namespace is the default namespace in which the K8s manifests rendered by the chart are associated
	Namespace string

	// ChartVersion is the semver of the Helm chart being used to render the original K8s manifests before various tweaks applied by helm-x,
	// or the chart version to be filled in the Chart.yaml of the temporary chart generated from K8s manifests or kustomize project.
	// In the latter case, this defaults to "1.0.0" if empty.
	ChartVersion string

	// AppVersion is the optional appVersion of the temporary chart.
	AppVersion string

	// EnableKustomizAlphaPlugins will add the `--enable_alpha_plugins` flag when running `kustomize build`
	EnableKustomizeAlphaPlugins bool

	Injectors []string
	Injects   []string

	AdhocChartDependencies           []ChartDependency
	DeprecatedAdhocChartDependencies []string

	JsonPatches           []string
	StrategicMergePatches []string

	// Transformers is the list of YAML files each defines a Kustomize transformer
	// See https://github.com/kubernetes-sigs/kustomize/blob/master/examples/configureBuiltinPlugin.md#configuring-the-builtin-plugins-instead for more information.
	Transformers []string

	// WorkaroundOutputDirIssue prevents chartify from using `helm template --output-dir` and let it use `helm template > some.yaml` instead to
	// workaround the potential helm issue
	// See https://github.com/roboll/helmfile/issues/1279#issuecomment-636839395
	WorkaroundOutputDirIssue bool

	// OverrideNamespace modifies namespace of every resource after rendering and patching,
	// as a workaround to fix a broken chart.
	// For kustomization, `Namespace` should just work and this won't be needed.
	// For helm chart, as long as the chart has "correct" resource templates with `namespace: {{ .Namespace }}`s this isn't needed.
	OverrideNamespace string

	// SkipDeps skips running `helm dep up` on the chart.
	// Useful for cases when the chart has a broken dependencies definition like seen in
	// https://github.com/roboll/helmfile/issues/1547
	SkipDeps bool

	// IncludeCRDs is a Helm 3 only option. When it is true, chartify passes a `--include-crds` flag
	// to helm-template.
	IncludeCRDs bool

	// Validate is a Helm 3 only option. When it is true, chartify passes --validate while running helm-template
	// It is required when your chart contains any template that relies on Capabilities.APIVersions
	// for rendering resourecs depending on the API resources and versions available on a live cluster.
	// In other words, setting this to true means that you need access to a Kubernetes cluster,
	// even if you aren't trying to install the generated chart onto the cluster.
	Validate bool

	// KubeVersion specifies the Kubernetes version used for Capabilities.KubeVersion
	// when running `helm template` to produce the temporary chart to apply various customizations.
	// If the upstream command that calls chartify was going to pass `kube-version` while rendering the original chart,
	// you must also pass the same value to this field.
	// Otherwise the temporary chart rendered by chartify lacks `kube-version` at helm-template time
	// and it my produce output unexpected to you.
	KubeVersion string

	// ApiVersions is a string of kubernetes APIVersions and passed to helm template via --api-versions
	// It is required if your chart contains any template that relies on Capabilities.APIVersion for rendering
	// resources depending on the API resources and versions available in a target cluster.
	// Setting this value defines a set of static capabilities and avoids the need for access to a live cluster during
	// templating in contrast to --validate
	ApiVersions []string

	// TemplateFuncs is the FuncMap used while rendering .gotmpl files in the target directory
	TemplateFuncs template.FuncMap
	// TemplateData is the data available via {{ . }} within .gotmpl files
	TemplateData interface{}
}

func (*ChartifyOpts) SetChartifyOption

func (s *ChartifyOpts) SetChartifyOption(opts *ChartifyOpts) error

type Dependency

type Dependency struct {
	Name         string   `yaml:"name,omitempty"`
	Repository   string   `yaml:"repository,omitempty"`
	Condition    string   `yaml:"condition,omitempty"`
	Alias        string   `yaml:"alias,omitempty"`
	Version      string   `yaml:"version,omitempty"`
	ImportValues []string `yaml:"import-values,omitempty"`
}

type InjectOpts

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

type KustomizeBuildOption

type KustomizeBuildOption interface {
	SetKustomizeBuildOption(opts *KustomizeBuildOpts) error
}

type KustomizeBuildOpts

type KustomizeBuildOpts struct {
	ValuesFiles        []string
	SetValues          []string
	SetFlags           []string
	EnableAlphaPlugins bool
	Namespace          string
	HelmBinary         string
}

func (*KustomizeBuildOpts) SetKustomizeBuildOption

func (o *KustomizeBuildOpts) SetKustomizeBuildOption(opts *KustomizeBuildOpts) error

type KustomizeImage

type KustomizeImage struct {
	Name    string `yaml:"name"`
	NewName string `yaml:"newName"`
	NewTag  string `yaml:"newTag"`
	Digest  string `yaml:"digest"`
}

func (KustomizeImage) String

func (img KustomizeImage) String() string

type KustomizeOpts

type KustomizeOpts struct {
	Images     []KustomizeImage `yaml:"images"`
	NamePrefix string           `yaml:"namePrefix"`
	NameSuffix string           `yaml:"nameSuffix"`
	Namespace  string           `yaml:"namespace"`
}

type Option

type Option func(*Runner) error

func HelmBin

func HelmBin(b string) Option

func KustomizeBin added in v0.16.0

func KustomizeBin(b string) Option

func UseHelm3

func UseHelm3(u bool) Option

func WithLogf

func WithLogf(logf func(string, ...interface{})) Option

type PatchOption

type PatchOption interface {
	SetPatchOption(*PatchOpts) error
}

type PatchOpts

type PatchOpts struct {
	JsonPatches []string

	StrategicMergePatches []string

	Transformers []string

	// Kustomize alpha plugin enable flag.
	// Above Kustomize v3, it is `--enable-alpha-plugins`.
	// Below Kustomize v3 (including v3), it is `--enable_alpha_plugins`.
	EnableAlphaPlugins bool
}

func (*PatchOpts) SetPatchOption

func (o *PatchOpts) SetPatchOption(opts *PatchOpts) error

type ReplaceWithRenderedOpts

type ReplaceWithRenderedOpts struct {
	// Debug when set to true passes `--debug` flag to `helm` in order to enable debug logging
	Debug bool

	// ValuesFiles are a list of Helm chart values files
	ValuesFiles []string

	// SetValues is a list of adhoc Helm chart values being passed via helm's `--set` flags
	SetValues []string

	// SetFlags is the list of set flags like --set k=v, --set-file k=path, --set-string k=str
	// used while rendering the chart.
	SetFlags []string

	// Namespace is the default namespace in which the K8s manifests rendered by the chart are associated
	Namespace string

	// ChartVersion is the semver of the Helm chart being used to render the original K8s manifests before various tweaks applied by helm-x
	ChartVersion string

	// IncludeCRDs is a Helm 3 only option. When it is true, chartify passes a `--include-crds` flag
	// to helm-template.
	IncludeCRDs bool

	// Validate is a Helm 3 only option. When it is true, chartify passes --validate while running helm-template
	// It is required when your chart contains any template that relies on Capabilities.APIVersions
	// for rendering resourecs depending on the API resources and versions available on a live cluster.
	// In other words, setting this to true means that you need access to a Kubernetes cluster,
	// even if you aren't trying to install the generated chart onto the cluster.
	Validate bool

	// KubeVersion specifies the Kubernetes version used for Capabilities.KubeVersion
	// when running `helm template` to produce the temporary chart to apply various customizations.
	// If the upstream command that calls chartify was going to pass `kube-version` while rendering the original chart,
	// you must also pass the same value to this field.
	// Otherwise the temporary chart rendered by chartify lacks `kube-version` at helm-template time
	// and it my produce output unexpected to you.
	KubeVersion string

	// ApiVersions is a string of kubernetes APIVersions and passed to helm template via --api-versions
	// It is required if your chart contains any template that relies on Capabilities.APIVersion for rendering
	// resources depending on the API resources and versions available in a target cluster.
	// Setting this value defines a set of static capabilities and avoids the need for access to a live cluster during
	// templating in contrast to --validate
	ApiVersions []string

	// WorkaroundOutputDirIssue prevents chartify from using `helm template --output-dir` and let it use `helm template > some.yaml` instead to
	// workaround the potential helm issue
	// See https://github.com/roboll/helmfile/issues/1279#issuecomment-636839395
	WorkaroundOutputDirIssue bool
}

type Requirements

type Requirements struct {
	Dependencies []Dependency `yaml:"dependencies,omitempty"`
}

type RunCommandFunc

type RunCommandFunc func(name string, args []string, dir string, stdout, stderr io.Writer, env map[string]string) error

type Runner

type Runner struct {
	// HelmBinary is the name or the path to `helm` command
	HelmBinary string

	// KustomizeBinary is the name or the path to `kustomize` command
	KustomizeBinary string

	RunCommand RunCommandFunc

	CopyFile    func(src, dst string) error
	WriteFile   func(filename string, data []byte, perm os.FileMode) error
	ReadFile    func(filename string) ([]byte, error)
	ReadDir     func(dirname string) ([]os.DirEntry, error)
	Walk        func(root string, walkFn filepath.WalkFunc) error
	MakeTempDir func(release, chart string, opts *ChartifyOpts) string
	Exists      func(path string) (bool, error)

	// Logf is the alternative log function used by chartify
	Logf func(string, ...interface{})
	// contains filtered or unexported fields
}

func New

func New(opts ...Option) *Runner

func (*Runner) Chartify

func (r *Runner) Chartify(release, dirOrChart string, opts ...ChartifyOption) (string, error)

Chartify creates a temporary Helm chart from a directory or a remote chart, and applies various transformations. Returns the full path to the temporary directory containing the generated chart if succeeded.

Parameters: * `release` is the name of Helm release being installed nolint

func (*Runner) EnsureFilesDir

func (r *Runner) EnsureFilesDir(tempDir string) (string, error)

func (*Runner) Inject

func (r *Runner) Inject(files []string, o InjectOpts) error

func (*Runner) IsHelm3

func (r *Runner) IsHelm3() bool

func (*Runner) KustomizeBuild

func (r *Runner) KustomizeBuild(srcDir string, tempDir string, opts ...KustomizeBuildOption) (string, error)

func (*Runner) Patch

func (r *Runner) Patch(tempDir string, generatedManifestFiles []string, opts ...PatchOption) error

nolint

func (*Runner) ReadAdhocDependencies

func (r *Runner) ReadAdhocDependencies(u *ChartifyOpts) ([]Dependency, error)

func (*Runner) ReplaceWithRendered

func (r *Runner) ReplaceWithRendered(name, chartName, chartPath string, o ReplaceWithRenderedOpts) ([]string, error)

func (*Runner) RewriteChartToPreventDoubleRendering

func (r *Runner) RewriteChartToPreventDoubleRendering(tempDir, filesDir string) error

RewriteChartToPreventDoubleRendering rewrites templates/*.yaml files with template files containing:

{{ .Files.Get "path/to/the/yaml/file" }}

So that re-running helm-template on chartify's final output doesn't result in double-rendering. Double-rendering accidentally renders e.g. go template expressions embedded in prometheus rules manifests, which is not what the user wants.

func (*Runner) SearchFiles

func (r *Runner) SearchFiles(o SearchFileOpts) ([]string, error)

SearchFiles returns a slice of files that are within the base path, has a matching sub path and file type

func (*Runner) SetNamespace

func (r *Runner) SetNamespace(tempDir, ns string) error

SetNamespace is a poor-man's `kubectl apply -f DIR --dry-run -o yaml --namespace NAMESPACE`

func (*Runner) UpdateRequirements

func (r *Runner) UpdateRequirements(replace bool, chartYamlPath, tempDir string, deps []Dependency) ([]Dependency, error)

UpdateRequirements updates either Chart.yaml's dependencies(helm 3) or requirements.yaml(helm 2) so that our subsequent run of `helm dep up` can fulfill missing chart dependencies. If it's a remote chart, only adhoc dependencies needs to be downloaded by `helm dep up` because the original chart dependencies shold have been already fetched by preceding `helm fetch`. If it's a local chart, unlike a remote chart there is not preceding step like `helm fetch` to download chart dependencies, `helm dep up` needs to download all the original + adhoc dependencies.

It returns an concatenated list of dependencies, including the original and the adhoc dependencies. The list is intended to be used as the requirements for `helm template`. At `helm template` run time, we already have all the dependencies under the `charts/` directory thanks to this function. But requirements are still needed in particular for `condition` fields, which controls whether to render the dependency chart or not in the end.

type SearchFileOpts

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

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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