Documentation
¶
Overview ¶
Package lint2 provides linting functionality for Replicated resources that integrates with the replicated CLI tool resolver infrastructure.
This package enables automatic downloading and execution of linting commands for:
- Helm charts (via helm lint)
- Preflight specs (via preflight lint from troubleshoot.sh)
- Support Bundle specs (via support-bundle lint from troubleshoot.sh)
Features ¶
Common functionality across all linters:
- Resource path expansion (including glob patterns)
- Resource validation (ensuring valid structure)
- Binary resolution via tool-resolver (automatic download/caching)
- Output parsing into structured results
- Support for custom tool versions
Glob pattern support (powered by doublestar library):
- Basic patterns: * (any chars), ? (one char), [abc] (char class)
- Recursive matching: ** (matches zero or more directories)
- Brace expansion: {alt1,alt2} (matches alternatives)
- Pattern validation: Early syntax checking during config parse
Helm-specific:
- Chart directory validation (Chart.yaml presence)
- Multi-chart linting with summary results
Troubleshoot (Preflight/Support Bundle) specific:
- Multi-document YAML parsing with yaml.NewDecoder
- JSON output parsing with generic type-safe implementation
- Auto-discovery of Support Bundles from manifest files
Usage ¶
The typical workflow for any linter is:
- Load configuration using tools.ConfigParser
- Extract and validate resource paths
- Resolve tool binary (downloads if not cached)
- Execute lint command on each resource
- Parse and display results
Example - Helm Charts ¶
parser := tools.NewConfigParser()
config, err := parser.FindAndParseConfig(".")
if err != nil {
return err
}
chartPaths, err := lint2.GetChartPathsFromConfig(config)
if err != nil {
return err
}
for _, chartPath := range chartPaths {
result, err := lint2.LintChart(ctx, chartPath, helmVersion)
if err != nil {
return err
}
// Process result...
}
Example - Preflight Specs ¶
preflightPaths, err := lint2.GetPreflightPathsFromConfig(config)
if err != nil {
return err
}
for _, specPath := range preflightPaths {
result, err := lint2.LintPreflight(ctx, specPath, preflightVersion)
if err != nil {
return err
}
// Process result...
}
Example - Support Bundle Specs ¶
// Support bundles are auto-discovered from manifest files
sbPaths, err := lint2.DiscoverSupportBundlesFromManifests(config.Manifests)
if err != nil {
return err
}
for _, specPath := range sbPaths {
result, err := lint2.LintSupportBundle(ctx, specPath, sbVersion)
if err != nil {
return err
}
// Process result...
}
Package lint2 provides linting functionality for Replicated resources. It supports linting Helm charts via helm lint and Preflight specs via preflight lint. Each linter executes the appropriate tool binary and parses the output into structured results.
Index ¶
- func BuildChartLookup(config *tools.Config) (map[string]*ChartWithMetadata, error)
- func ContainsGlob(path string) bool
- func DiscoverChartPaths(pattern string) ([]string, error)
- func DiscoverHelmChartManifests(manifestGlobs []string) (map[string]*HelmChartManifest, error)
- func DiscoverHelmChartPaths(pattern string) ([]string, error)
- func DiscoverPreflightPaths(pattern string) ([]string, error)
- func DiscoverSupportBundlePaths(pattern string) ([]string, error)
- func DiscoverSupportBundlesFromManifests(manifestGlobs []string) ([]string, error)
- func GetChartPathsFromConfig(config *tools.Config) ([]string, error)
- func GetPreflightPathsFromConfig(config *tools.Config) ([]string, error)
- func Glob(pattern string, opts ...GlobOption) ([]string, error)
- func GlobFiles(pattern string, opts ...GlobOption) ([]string, error)
- func ValidateGlobPattern(pattern string) error
- type ChartMetadata
- type ChartMissingHelmChartInfo
- type ChartNotFoundError
- type ChartToHelmChartValidationResult
- type ChartWithMetadata
- type DuplicateChartError
- type DuplicateHelmChartError
- type GitignoreChecker
- type GlobOption
- type GlobOptions
- type HelmChartManifest
- type LintMessage
- type LintResult
- func LintChart(ctx context.Context, chartPath string, helmVersion string) (*LintResult, error)
- func LintPreflight(ctx context.Context, specPath string, valuesPath string, chartName string, ...) (*LintResult, error)
- func LintSupportBundle(ctx context.Context, specPath string, sbVersion string) (*LintResult, error)
- type MultipleChartsMissingHelmChartsError
- type PreflightFileResult
- type PreflightLintIssue
- type PreflightLintResult
- type PreflightWithValues
- type SupportBundleFileResult
- type SupportBundleLintIssue
- type SupportBundleLintResult
- type TroubleshootFileResult
- type TroubleshootIssue
- type TroubleshootLintResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildChartLookup ¶ added in v0.118.0
func BuildChartLookup(config *tools.Config) (map[string]*ChartWithMetadata, error)
BuildChartLookup creates a name:version lookup map for charts. Returns error if duplicate chart name:version pairs are found. This utility is reusable by any code that needs to resolve charts by name:version.
func ContainsGlob ¶
ContainsGlob checks if a path contains glob wildcards (* ? [ {). Exported for use by config parsing to detect patterns that need validation.
func DiscoverChartPaths ¶
discoverChartPaths discovers Helm chart directories from a glob pattern. This is a thin wrapper around discoverDirsByMarkerFile for backward compatibility.
Supports patterns like:
- "./charts/**" (finds all charts recursively)
- "./charts/{app,api}/**" (finds charts in specific subdirectories)
- "./pkg/**/Chart.yaml" (explicit Chart.yaml pattern)
- "./my-chart" (explicit directory path - validated strictly)
func DiscoverHelmChartManifests ¶
func DiscoverHelmChartManifests(manifestGlobs []string) (map[string]*HelmChartManifest, error)
DiscoverHelmChartManifests scans manifest glob patterns and extracts HelmChart custom resources. It returns a map keyed by "name:chartVersion" for efficient lookup during preflight rendering.
Accepts HelmChart resources with any apiVersion (validation happens in the linter).
Returns an error if:
- manifestGlobs is empty (required to find builder values for templated preflights)
- Duplicate name:chartVersion pairs are found (ambiguous builder values)
- Glob expansion fails
Silently skips:
- Files that can't be read
- Files that aren't valid YAML
- Files that don't contain kind: HelmChart
- Hidden directories (.git, .github, etc.)
func DiscoverHelmChartPaths ¶ added in v0.118.0
DiscoverHelmChartPaths discovers HelmChart manifest files from a glob pattern. This is a thin wrapper around discoverYAMLsByKind for backward compatibility.
Supports patterns like:
- "./manifests/**" (finds all HelmChart manifests recursively)
- "./manifests/**/*.yaml" (explicit YAML extension)
- "./k8s/{dev,prod}/**/*.yaml" (environment-specific)
- "./helmchart.yaml" (explicit file path - validated strictly)
func DiscoverPreflightPaths ¶
discoverPreflightPaths discovers Preflight spec files from a glob pattern. This is a thin wrapper around discoverYAMLsByKind for backward compatibility.
Supports patterns like:
- "./preflights/**" (finds all Preflight specs recursively)
- "./preflights/**/*.yaml" (explicit YAML extension)
- "./k8s/{dev,prod}/**/*.yaml" (environment-specific)
- "./preflight.yaml" (explicit file path - validated strictly)
func DiscoverSupportBundlePaths ¶
discoverSupportBundlePaths discovers Support Bundle spec files from a glob pattern. This is a thin wrapper around discoverYAMLsByKind for backward compatibility.
Supports patterns like:
- "./manifests/**" (finds all Support Bundle specs recursively)
- "./manifests/**/*.yaml" (explicit YAML extension)
- "./k8s/{dev,prod}/**/*.yaml" (environment-specific)
- "./support-bundle.yaml" (explicit file path - validated strictly)
func DiscoverSupportBundlesFromManifests ¶
DiscoverSupportBundlesFromManifests discovers support bundle spec files from manifest glob patterns. It expands the glob patterns, reads each YAML file, and identifies files containing kind: SupportBundle. This allows support bundles to be co-located with other Kubernetes manifests without explicit configuration.
func GetChartPathsFromConfig ¶
GetChartPathsFromConfig extracts and expands chart paths from config
func GetPreflightPathsFromConfig ¶
GetPreflightPathsFromConfig extracts and expands preflight spec paths from config
func Glob ¶
func Glob(pattern string, opts ...GlobOption) ([]string, error)
Glob expands glob patterns using doublestar library, which supports: - * : matches any sequence of non-separator characters - ** : matches zero or more directories (recursive) - ? : matches any single character - [abc] : matches any character in the brackets - {alt1,alt2} : matches any of the alternatives
This is a wrapper around doublestar.FilepathGlob that provides: - Drop-in replacement for filepath.Glob - Recursive ** globbing (unlike stdlib filepath.Glob) - Brace expansion {a,b,c} - Optional gitignore filtering via WithGitignoreChecker option
func GlobFiles ¶
func GlobFiles(pattern string, opts ...GlobOption) ([]string, error)
GlobFiles expands glob patterns returning only files (not directories). Uses WithFilesOnly() option for efficient library-level filtering. This is useful for preflight specs and manifest discovery where only files should be processed. Supports optional gitignore filtering via WithGitignoreChecker option.
func ValidateGlobPattern ¶
ValidateGlobPattern checks if a pattern is valid doublestar glob syntax and does not contain path traversal attempts. This is useful for validating user input early before attempting to expand patterns. Returns an error if the pattern syntax is invalid or attempts path traversal.
Types ¶
type ChartMetadata ¶
ChartMetadata represents basic metadata from a Helm chart's Chart.yaml
func GetChartMetadata ¶
func GetChartMetadata(chartPath string) (*ChartMetadata, error)
GetChartMetadata reads Chart.yaml and returns the chart name and version
type ChartMissingHelmChartInfo ¶ added in v0.118.0
type ChartMissingHelmChartInfo struct {
ChartPath string // Absolute path to chart directory
ChartName string // Chart name from Chart.yaml
ChartVersion string // Chart version from Chart.yaml
}
ChartMissingHelmChartInfo contains information about a chart missing its HelmChart manifest.
type ChartNotFoundError ¶ added in v0.118.0
type ChartNotFoundError struct {
RequestedChart string // "name:version"
AvailableCharts []string // List of available chart keys
}
ChartNotFoundError is returned when a preflight references a chart that doesn't exist in the config.
func (*ChartNotFoundError) Error ¶ added in v0.118.0
func (e *ChartNotFoundError) Error() string
type ChartToHelmChartValidationResult ¶ added in v0.118.0
type ChartToHelmChartValidationResult struct {
Warnings []string // Non-fatal issues (orphaned HelmChart manifests)
}
ChartToHelmChartValidationResult contains validation results and warnings
func ValidateChartToHelmChartMapping ¶ added in v0.118.0
func ValidateChartToHelmChartMapping( charts []ChartWithMetadata, helmChartManifests map[string]*HelmChartManifest, ) (*ChartToHelmChartValidationResult, error)
ValidateChartToHelmChartMapping validates that every chart has a corresponding HelmChart manifest.
Requirements:
- Every chart in charts must have a matching HelmChart manifest in helmChartManifests
- Matching key format: "chartName:chartVersion"
Returns:
- result: Contains warnings (orphaned HelmChart manifests)
- error: Hard error if any chart is missing its HelmChart manifest (batch reports all missing)
Behavior:
- Hard error: Chart exists but no matching HelmChart manifest (collects ALL missing, reports together)
- Warning: HelmChart manifest exists but no matching chart configured
- Duplicate HelmChart manifests are detected in DiscoverHelmChartManifests()
type ChartWithMetadata ¶
type ChartWithMetadata struct {
Path string // Absolute path to the chart directory
Name string // Chart name from Chart.yaml
Version string // Chart version from Chart.yaml
}
ChartWithMetadata pairs a chart path with its metadata from Chart.yaml
func GetChartsWithMetadataFromConfig ¶
func GetChartsWithMetadataFromConfig(config *tools.Config) ([]ChartWithMetadata, error)
GetChartsWithMetadataFromConfig extracts chart paths and their metadata from config This function combines GetChartPathsFromConfig with metadata extraction, reducing boilerplate for callers that need both path and metadata information (like image extraction).
type DuplicateChartError ¶ added in v0.118.0
type DuplicateChartError struct {
ChartKey string // "name:version"
FirstPath string
SecondPath string
}
DuplicateChartError is returned when multiple charts have the same name:version.
func (*DuplicateChartError) Error ¶ added in v0.118.0
func (e *DuplicateChartError) Error() string
type DuplicateHelmChartError ¶
type DuplicateHelmChartError struct {
ChartKey string // "name:chartVersion"
FirstFile string
SecondFile string
}
DuplicateHelmChartError is returned when multiple HelmChart manifests are found with the same name:chartVersion combination.
func (*DuplicateHelmChartError) Error ¶
func (e *DuplicateHelmChartError) Error() string
type GitignoreChecker ¶ added in v0.118.0
type GitignoreChecker struct {
// contains filtered or unexported fields
}
GitignoreChecker checks if paths should be ignored based on .gitignore rules. It supports repository .gitignore files, .git/info/exclude, and global gitignore.
func NewGitignoreChecker ¶ added in v0.118.0
func NewGitignoreChecker(baseDir string) (*GitignoreChecker, error)
NewGitignoreChecker creates a new GitignoreChecker for the given base directory. It loads all gitignore sources (repository .gitignore files, .git/info/exclude, and global gitignore). Returns nil, nil if no gitignore files are found (not an error). Errors are only returned for critical failures like invalid baseDir.
func (*GitignoreChecker) PathMatchesIgnoredPattern ¶ added in v0.118.0
func (g *GitignoreChecker) PathMatchesIgnoredPattern(configPath string) bool
PathMatchesIgnoredPattern checks if a config path explicitly references a gitignored pattern and should bypass gitignore checking.
This implements the "explicit bypass" rule: if a user specifies a path that contains a gitignored pattern (e.g., "./vendor/**" when "vendor/" is gitignored), we assume they want to lint that path anyway.
Examples:
- "./vendor/**" when "vendor/" is gitignored -> true (bypass)
- "./dist/chart" when "dist/" is gitignored -> true (bypass)
- "./charts/**" when "vendor/" is gitignored -> false (respect gitignore)
func (*GitignoreChecker) ShouldIgnore ¶ added in v0.118.0
func (g *GitignoreChecker) ShouldIgnore(path string) bool
ShouldIgnore checks if a path should be ignored based on gitignore rules. Returns true if the path matches any gitignore pattern. Path can be absolute or relative to the base directory.
type GlobOption ¶ added in v0.118.0
type GlobOption func(*GlobOptions)
GlobOption is a functional option for configuring glob operations.
func WithGitignoreChecker ¶ added in v0.118.0
func WithGitignoreChecker(checker *GitignoreChecker) GlobOption
WithGitignoreChecker returns a GlobOption that enables gitignore filtering.
type GlobOptions ¶ added in v0.118.0
type GlobOptions struct {
GitignoreChecker *GitignoreChecker
}
GlobOptions contains options for glob operations.
type HelmChartManifest ¶
type HelmChartManifest struct {
Name string // spec.chart.name - must match Chart.yaml name
ChartVersion string // spec.chart.chartVersion - must match Chart.yaml version
BuilderValues map[string]interface{} // spec.builder - values for air gap bundle rendering (can be nil/empty)
FilePath string // Source file path for error reporting
}
HelmChartManifest represents a parsed KOTS HelmChart custom resource. It contains the fields needed to match charts with their builder values for preflight template rendering.
func FindHelmChartManifest ¶
func FindHelmChartManifest(chartName, chartVersion string, manifests map[string]*HelmChartManifest) *HelmChartManifest
FindHelmChartManifest looks up a HelmChart manifest by chart name and version. The matching key format is "name:version" which must exactly match both the chart metadata and the HelmChart manifest's spec.chart.name and spec.chart.chartVersion. Returns nil if no matching manifest is found.
type LintMessage ¶
type LintMessage struct {
Severity string // "ERROR", "WARNING", "INFO"
Path string // File path (if provided by helm)
Message string // The lint message
}
LintMessage represents a single finding from helm lint
type LintResult ¶
type LintResult struct {
Success bool
Messages []LintMessage
}
LintResult represents the outcome of linting a chart
func LintChart ¶
LintChart executes helm lint on the given chart path and returns structured results
func LintPreflight ¶
func LintPreflight( ctx context.Context, specPath string, valuesPath string, chartName string, chartVersion string, helmChartManifests map[string]*HelmChartManifest, preflightVersion string, ) (*LintResult, error)
LintPreflight executes preflight lint on the given spec path and returns structured results. The preflight CLI tool handles template rendering and validation internally. For v1beta3 specs, we validate that HelmChart manifests exist and extract builder values.
func LintSupportBundle ¶
LintSupportBundle executes support-bundle lint on the given spec path and returns structured results
type MultipleChartsMissingHelmChartsError ¶ added in v0.118.0
type MultipleChartsMissingHelmChartsError struct {
MissingCharts []ChartMissingHelmChartInfo
}
MultipleChartsMissingHelmChartsError is returned when multiple charts are missing HelmChart manifests.
func (*MultipleChartsMissingHelmChartsError) Error ¶ added in v0.118.0
func (e *MultipleChartsMissingHelmChartsError) Error() string
type PreflightFileResult ¶
type PreflightFileResult struct {
FilePath string `json:"filePath"`
Errors []PreflightLintIssue `json:"errors"`
Warnings []PreflightLintIssue `json:"warnings"`
Infos []PreflightLintIssue `json:"infos"`
}
type PreflightLintIssue ¶
type PreflightLintIssue struct {
Line int `json:"line"`
Column int `json:"column"`
Message string `json:"message"`
Field string `json:"field"`
}
func (PreflightLintIssue) GetColumn ¶
func (i PreflightLintIssue) GetColumn() int
func (PreflightLintIssue) GetField ¶
func (i PreflightLintIssue) GetField() string
func (PreflightLintIssue) GetLine ¶
func (i PreflightLintIssue) GetLine() int
Implement TroubleshootIssue interface for PreflightLintIssue
func (PreflightLintIssue) GetMessage ¶
func (i PreflightLintIssue) GetMessage() string
type PreflightLintResult ¶
type PreflightLintResult struct {
Results []PreflightFileResult `json:"results"`
}
PreflightLintResult represents the JSON output from preflight lint
type PreflightWithValues ¶
type PreflightWithValues struct {
SpecPath string // Path to the preflight spec file
ValuesPath string // Path to values.yaml (optional - passed to preflight lint if provided)
ChartName string // Chart name from Chart.yaml (used to look up HelmChart manifest for builder values)
ChartVersion string // Chart version from Chart.yaml (used to look up HelmChart manifest for builder values)
}
PreflightWithValues contains preflight spec path and optional values file
func GetPreflightWithValuesFromConfig ¶
func GetPreflightWithValuesFromConfig(config *tools.Config) ([]PreflightWithValues, error)
GetPreflightWithValuesFromConfig extracts preflight paths with optional chart/values information. If chartName/chartVersion are provided, uses explicit chart references. If not provided, returns empty values and lets the linter decide requirements.
type SupportBundleFileResult ¶
type SupportBundleFileResult struct {
FilePath string `json:"filePath"`
Errors []SupportBundleLintIssue `json:"errors"`
Warnings []SupportBundleLintIssue `json:"warnings"`
Infos []SupportBundleLintIssue `json:"infos"`
}
type SupportBundleLintIssue ¶
type SupportBundleLintIssue struct {
Line int `json:"line"`
Column int `json:"column"`
Message string `json:"message"`
Field string `json:"field"`
}
func (SupportBundleLintIssue) GetColumn ¶
func (i SupportBundleLintIssue) GetColumn() int
func (SupportBundleLintIssue) GetField ¶
func (i SupportBundleLintIssue) GetField() string
func (SupportBundleLintIssue) GetLine ¶
func (i SupportBundleLintIssue) GetLine() int
Implement TroubleshootIssue interface for SupportBundleLintIssue
func (SupportBundleLintIssue) GetMessage ¶
func (i SupportBundleLintIssue) GetMessage() string
type SupportBundleLintResult ¶
type SupportBundleLintResult struct {
Results []SupportBundleFileResult `json:"results"`
}
SupportBundleLintResult represents the JSON output from support-bundle lint This structure mirrors PreflightLintResult since both tools come from the same troubleshoot repository and share the same validation infrastructure.
type TroubleshootFileResult ¶
type TroubleshootFileResult[T TroubleshootIssue] struct { FilePath string `json:"filePath"` Errors []T `json:"errors"` Warnings []T `json:"warnings"` Infos []T `json:"infos"` }
TroubleshootFileResult represents the common structure for file-level results from troubleshoot.sh linting tools (preflight, support-bundle, etc.)
type TroubleshootIssue ¶
type TroubleshootIssue interface {
GetLine() int
GetColumn() int
GetMessage() string
GetField() string
}
TroubleshootIssue is an interface that both PreflightLintIssue and SupportBundleLintIssue satisfy, allowing common formatting logic. Both tools come from the troubleshoot.sh repository and share the same validation infrastructure and output format.
type TroubleshootLintResult ¶
type TroubleshootLintResult[T TroubleshootIssue] struct { Results []TroubleshootFileResult[T] `json:"results"` }
TroubleshootLintResult represents the common JSON structure for troubleshoot.sh linting tool output