goloader

package
v1.11.0 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2026 License: Apache-2.0 Imports: 30 Imported by: 0

Documentation

Overview

Package goloader provides functionality to load and process Go-based KubeVela definitions. It supports loading definitions from Go source files and converting them to CUE format.

Index

Constants

View Source
const (
	// DefaultScriptTimeout is the default timeout for script execution
	DefaultScriptTimeout = 30 * time.Second
	// DefaultWaitTimeout is the default timeout for waiting on resources
	DefaultWaitTimeout = 5 * time.Minute
	// DefaultPollInterval is the polling interval when waiting for resources
	DefaultPollInterval = 2 * time.Second
)
View Source
const GoExtension = ".go"

GoExtension is the file extension for Go files

Variables

This section is empty.

Functions

func DiscoverDefinitions

func DiscoverDefinitions(dir string) ([]string, error)

DiscoverDefinitions finds Go files that contain defkit definitions in a directory

func GenerateCUEFromGoFile

func GenerateCUEFromGoFile(filePath string, defInfo DefinitionInfo) (string, error)

GenerateCUEFromGoFile generates CUE from a Go definition file This uses a code generation approach: it creates a temporary Go program that imports the definition and calls ToCue() on it

func IsGoDefinitionFile

func IsGoDefinitionFile(path string) (bool, error)

IsGoDefinitionFile checks if a Go file likely contains defkit definitions by looking for defkit imports

func IsGoFile

func IsGoFile(path string) bool

IsGoFile checks if a file is a Go source file (not a test file)

func SupportsRegistry

func SupportsRegistry(moduleRoot string) bool

SupportsRegistry checks if a module uses the registry pattern. It checks for the presence of cmd/register/main.go which is the conventional entry point for registry-based definition loading.

func ValidateModule

func ValidateModule(module *LoadedModule, velaVersion string) []error

ValidateModule validates a module for correctness and compatibility

Types

type DefinitionInfo

type DefinitionInfo struct {
	// Name is the definition name (e.g., "webservice", "daemon")
	Name string
	// Type is the definition type (e.g., "component", "trait", "policy", "workflow-step")
	Type string
	// FunctionName is the Go function that returns the definition
	FunctionName string
	// FilePath is the path to the Go file containing the definition
	FilePath string
	// PackageName is the Go package name
	PackageName string
	// Placement contains the definition-level placement constraints (if any)
	Placement *DefinitionPlacement
}

DefinitionInfo holds information about a discovered Go definition

func AnalyzeGoFile

func AnalyzeGoFile(filePath string) ([]DefinitionInfo, error)

AnalyzeGoFile analyzes a Go file and extracts definition function information

func ListModuleDefinitions

func ListModuleDefinitions(ctx context.Context, moduleRef string, opts ModuleLoadOptions) ([]DefinitionInfo, error)

ListModuleDefinitions returns information about definitions in a module without loading them

type DefinitionPlacement

type DefinitionPlacement struct {
	// RunOn specifies conditions that must be satisfied for the definition to run.
	RunOn []PlacementCondition `json:"runOn,omitempty"`
	// NotRunOn specifies conditions that exclude clusters from running the definition.
	NotRunOn []PlacementCondition `json:"notRunOn,omitempty"`
}

DefinitionPlacement holds placement constraints for a definition. This is extracted from the definition's Go code.

func (*DefinitionPlacement) IsEmpty

func (p *DefinitionPlacement) IsEmpty() bool

IsEmpty returns true if no placement constraints are defined.

func (*DefinitionPlacement) ToPlacementSpec

func (p *DefinitionPlacement) ToPlacementSpec() placement.PlacementSpec

ToPlacementSpec converts DefinitionPlacement to placement.PlacementSpec.

type GeneratorEnvironment

type GeneratorEnvironment struct {
	// TempDir is the temporary directory with go.mod already set up
	TempDir string
	// ModuleRoot is the root directory of the user's Go module
	ModuleRoot string
	// ModuleName is the Go module name from go.mod
	ModuleName string
	// contains filtered or unexported fields
}

GeneratorEnvironment manages a reusable temp directory for CUE generation. This avoids running `go mod tidy` for each definition - it runs only ONCE per module.

func NewGeneratorEnvironment

func NewGeneratorEnvironment(moduleRoot string) (*GeneratorEnvironment, error)

NewGeneratorEnvironment creates a new generator environment for a module. It sets up the temp directory and runs `go mod tidy` ONCE.

func (*GeneratorEnvironment) Close

func (env *GeneratorEnvironment) Close() error

Close cleans up the temporary directory

func (*GeneratorEnvironment) GenerateCUE

func (env *GeneratorEnvironment) GenerateCUE(filePath string, defInfo DefinitionInfo) (string, error)

GenerateCUE generates CUE for a single definition, reusing the pre-configured environment. This is much faster than GenerateCUEFromGoFile because it doesn't run `go mod tidy`. Note: This method is thread-safe but serializes access. For parallel processing, use GenerateCUEParallel which creates separate files for each worker.

func (*GeneratorEnvironment) GenerateCUEParallel

func (env *GeneratorEnvironment) GenerateCUEParallel(definitions []DefinitionInfo) []LoadResult

GenerateCUEParallel generates CUE for multiple definitions in parallel. It uses worker goroutines to process definitions concurrently. Each worker uses a unique filename to avoid conflicts.

type Hook

type Hook struct {
	// Path is a directory containing YAML manifests to apply
	// Files are processed in alphabetical order (use numeric prefixes for ordering)
	Path string `yaml:"path,omitempty" json:"path,omitempty"`
	// Script is a path to a shell script to execute
	Script string `yaml:"script,omitempty" json:"script,omitempty"`
	// Wait indicates whether to wait for resources to be ready (for Path hooks)
	Wait bool `yaml:"wait,omitempty" json:"wait,omitempty"`
	// WaitFor specifies the readiness condition to wait for.
	// Can be a simple condition name (e.g., "Ready", "Established") or
	// a CUE expression (e.g., 'status.phase == "Running"').
	// Only used when Wait is true.
	WaitFor string `yaml:"waitFor,omitempty" json:"waitFor,omitempty"`
	// Optional indicates whether hook failure should stop the process
	Optional bool `yaml:"optional,omitempty" json:"optional,omitempty"`
	// Timeout for the hook execution (default: 5m for wait, 30s for scripts)
	Timeout string `yaml:"timeout,omitempty" json:"timeout,omitempty"`
}

Hook represents a single hook action

func (*Hook) Validate

func (hook *Hook) Validate() error

Validate checks that the hook configuration is valid

type HookDetail

type HookDetail struct {
	// Name is the hook name (path or script)
	Name string
	// Duration is how long the hook took to execute
	Duration time.Duration
	// Wait indicates if this hook waited for resources
	Wait bool
	// ResourcesCreated is resources created by this hook
	ResourcesCreated int
	// ResourcesUpdated is resources updated by this hook
	ResourcesUpdated int
}

HookDetail contains information about a single hook execution

type HookExecutionStats

type HookExecutionStats struct {
	// TotalDuration is the total time spent executing hooks
	TotalDuration time.Duration
	// HookDetails contains per-hook timing information
	HookDetails []HookDetail
	// ResourcesCreated is the number of resources created by path hooks
	ResourcesCreated int
	// ResourcesUpdated is the number of resources updated by path hooks
	ResourcesUpdated int
	// OptionalFailed is the number of optional hooks that failed
	OptionalFailed int
}

HookExecutionStats contains statistics from hook execution

type HookExecutor

type HookExecutor struct {
	// Client is the Kubernetes client for applying manifests
	Client client.Client
	// ModulePath is the base path of the module
	ModulePath string
	// Namespace is the target namespace for resources
	Namespace string
	// DryRun indicates whether to perform a dry run
	DryRun bool
	// Streams provides output streams for logging
	Streams util.IOStreams
}

HookExecutor handles the execution of module hooks

func NewHookExecutor

func NewHookExecutor(c client.Client, modulePath, namespace string, dryRun bool, streams util.IOStreams) *HookExecutor

NewHookExecutor creates a new HookExecutor

func (*HookExecutor) ExecuteHooks

func (e *HookExecutor) ExecuteHooks(ctx context.Context, phase string, hooks []Hook) (*HookExecutionStats, error)

ExecuteHooks runs a list of hooks in order and returns execution statistics

type LoadResult

type LoadResult struct {
	// CUE is the generated CUE string
	CUE string
	// YAML is the generated YAML string (Kubernetes CR format)
	YAML []byte
	// Definition contains metadata about the definition
	Definition DefinitionInfo
	// Error is set if loading failed for this definition
	Error error
}

LoadResult contains the result of loading Go definitions

func LoadFromDirectory

func LoadFromDirectory(dir string) ([]LoadResult, error)

LoadFromDirectory loads all Go definition files from a directory

func LoadFromDirectoryOptimized

func LoadFromDirectoryOptimized(dir string) ([]LoadResult, error)

LoadFromDirectoryOptimized loads all Go definition files from a directory with optimized performance. It creates a generator environment once, runs `go mod tidy` once, then processes all definitions. This is the recommended function for loading multiple definitions from a module.

func LoadFromDirectoryWithEnv

func LoadFromDirectoryWithEnv(env *GeneratorEnvironment, dir string) ([]LoadResult, error)

LoadFromDirectoryWithEnv loads all Go definition files from a directory using a pre-configured environment. This is much faster than LoadFromDirectory because it runs `go mod tidy` only once.

func LoadFromFile

func LoadFromFile(filePath string) ([]LoadResult, error)

LoadFromFile loads a Go definition file and returns the generated CUE. If the file contains no definitions (e.g., helper files with shared types), it returns an empty slice without error.

func LoadFromFileWithEnv

func LoadFromFileWithEnv(env *GeneratorEnvironment, filePath string) ([]LoadResult, error)

LoadFromFileWithEnv loads a Go definition file using a pre-configured generator environment. This is more efficient than LoadFromFile when loading multiple files from the same module.

func LoadFromModuleAuto

func LoadFromModuleAuto(moduleRoot string) ([]LoadResult, error)

LoadFromModuleAuto automatically selects the best loading strategy: - If the module uses defkit.Register(), use the registry approach - Otherwise, fall back to the AST-based approach

func LoadFromModuleWithRegistry

func LoadFromModuleWithRegistry(moduleRoot string) ([]LoadResult, error)

LoadFromModuleWithRegistry loads definitions from a Go module using the registry pattern. This is the simplest and most efficient approach - it requires: 1. Each definition file has init() that calls defkit.Register() 2. Module has cmd/register/main.go that imports all packages and outputs JSON

How it works: 1. Run `go run ./cmd/register` in the module directory 2. The main.go imports all definition packages (triggering init() functions) 3. init() functions call defkit.Register() for each definition 4. main() calls defkit.ToJSON() to output all registered definitions 5. CLI parses the JSON output

This approach: - No temp directory needed - No go mod tidy needed (module is already set up) - Runs `go run` exactly ONCE - No AST parsing required - Fastest possible loading

type LoadedModule

type LoadedModule struct {
	// Metadata is the module metadata
	Metadata ModuleMetadata
	// Path is the local filesystem path to the module
	Path string
	// ModulePath is the Go module path (e.g., github.com/myorg/defs)
	ModulePath string
	// Version is the resolved version
	Version string
	// Definitions contains all discovered definitions
	Definitions []LoadResult
	// Dependencies are the resolved dependencies
	Dependencies []*LoadedModule
}

LoadedModule represents a loaded definition module

func LoadModule

func LoadModule(ctx context.Context, moduleRef string, opts ModuleLoadOptions) (*LoadedModule, error)

LoadModule loads a definition module from a path or Go module reference. Supports:

  • Local paths: ./my-defs, /absolute/path/to/defs
  • Go modules: github.com/myorg/defs@v1.0.0

func (*LoadedModule) GetComponents

func (m *LoadedModule) GetComponents() []LoadResult

GetComponents returns all component definitions

func (*LoadedModule) GetDefinitionsByType

func (m *LoadedModule) GetDefinitionsByType(defType string) []LoadResult

GetDefinitionsByType returns definitions filtered by type

func (*LoadedModule) GetPolicies

func (m *LoadedModule) GetPolicies() []LoadResult

GetPolicies returns all policy definitions

func (*LoadedModule) GetTraits

func (m *LoadedModule) GetTraits() []LoadResult

GetTraits returns all trait definitions

func (*LoadedModule) GetWorkflowSteps

func (m *LoadedModule) GetWorkflowSteps() []LoadResult

GetWorkflowSteps returns all workflow step definitions

func (*LoadedModule) Summary

func (m *LoadedModule) Summary() string

Summary returns a summary of the module contents

type Maintainer

type Maintainer struct {
	Name  string `yaml:"name" json:"name"`
	Email string `yaml:"email,omitempty" json:"email,omitempty"`
}

Maintainer represents a module maintainer

type ModuleDependency

type ModuleDependency struct {
	// Module is the Go module path
	Module string `yaml:"module" json:"module"`
	// Version is the required version (supports semver constraints)
	Version string `yaml:"version" json:"version"`
}

ModuleDependency represents a dependency on another module

type ModuleHooks

type ModuleHooks struct {
	// PreApply hooks run before definitions are applied
	PreApply []Hook `yaml:"pre-apply,omitempty" json:"pre-apply,omitempty"`
	// PostApply hooks run after definitions are applied
	PostApply []Hook `yaml:"post-apply,omitempty" json:"post-apply,omitempty"`
}

ModuleHooks defines lifecycle hooks for module application

func (*ModuleHooks) HasPostApply

func (h *ModuleHooks) HasPostApply() bool

HasPostApply returns true if post-apply hooks are defined

func (*ModuleHooks) HasPreApply

func (h *ModuleHooks) HasPreApply() bool

HasPreApply returns true if pre-apply hooks are defined

func (*ModuleHooks) IsEmpty

func (h *ModuleHooks) IsEmpty() bool

IsEmpty returns true if no hooks are defined

type ModuleLoadOptions

type ModuleLoadOptions struct {
	// Version specifies the version to load (for remote modules)
	Version string
	// Types filters which definition types to load
	Types []string
	// NamePrefix adds a prefix to all definition names
	NamePrefix string
	// IncludeTests includes test files
	IncludeTests bool
	// ResolveDependencies resolves and loads dependencies
	ResolveDependencies bool
}

ModuleLoadOptions configures module loading

func DefaultModuleLoadOptions

func DefaultModuleLoadOptions() ModuleLoadOptions

DefaultModuleLoadOptions returns default options

type ModuleMetadata

type ModuleMetadata struct {
	// APIVersion is the metadata API version
	APIVersion string `yaml:"apiVersion" json:"apiVersion"`
	// Kind should be "DefinitionModule"
	Kind string `yaml:"kind" json:"kind"`
	// Metadata contains name and version
	Metadata ModuleObjectMeta `yaml:"metadata" json:"metadata"`
	// Spec contains module configuration
	Spec ModuleSpec `yaml:"spec" json:"spec"`
}

ModuleMetadata contains metadata about a definition module. This is read from module.yaml in the module root.

type ModuleObjectMeta

type ModuleObjectMeta struct {
	// Name is the module name
	Name string `yaml:"name" json:"name"`
}

ModuleObjectMeta contains module identification

type ModulePlacement

type ModulePlacement struct {
	// RunOn specifies conditions that must be satisfied for definitions to be applied.
	RunOn []ModulePlacementCondition `yaml:"runOn,omitempty" json:"runOn,omitempty"`
	// NotRunOn specifies conditions that exclude clusters from running definitions.
	NotRunOn []ModulePlacementCondition `yaml:"notRunOn,omitempty" json:"notRunOn,omitempty"`
}

ModulePlacement defines placement constraints at the module level. This is a YAML-parseable representation that gets converted to placement.PlacementSpec.

func (*ModulePlacement) IsEmpty

func (p *ModulePlacement) IsEmpty() bool

IsEmpty returns true if no placement constraints are defined.

func (*ModulePlacement) ToPlacementSpec

func (p *ModulePlacement) ToPlacementSpec() placement.PlacementSpec

ToPlacementSpec converts the YAML-parsed ModulePlacement to a placement.PlacementSpec that can be used for evaluation.

type ModulePlacementCondition

type ModulePlacementCondition struct {
	// Key is the cluster label key to match against.
	Key string `yaml:"key" json:"key"`
	// Operator is the comparison operator (Eq, Ne, In, NotIn, Exists, NotExists).
	Operator string `yaml:"operator" json:"operator"`
	// Values are the values to compare against.
	Values []string `yaml:"values,omitempty" json:"values,omitempty"`
}

ModulePlacementCondition represents a single placement condition in YAML format.

func (ModulePlacementCondition) ToCondition

ToCondition converts a ModulePlacementCondition to a placement.Condition.

type ModuleSpec

type ModuleSpec struct {
	// Description is a human-readable description
	Description string `yaml:"description,omitempty" json:"description,omitempty"`
	// Maintainers lists the module maintainers
	Maintainers []Maintainer `yaml:"maintainers,omitempty" json:"maintainers,omitempty"`
	// MinVelaVersion is the minimum KubeVela version required
	MinVelaVersion string `yaml:"minVelaVersion,omitempty" json:"minVelaVersion,omitempty"`
	// MinDefkitVersion is the minimum defkit SDK version
	MinDefkitVersion string `yaml:"minDefkitVersion,omitempty" json:"minDefkitVersion,omitempty"`
	// Categories for organization
	Categories []string `yaml:"categories,omitempty" json:"categories,omitempty"`
	// Dependencies lists other definition modules this depends on
	Dependencies []ModuleDependency `yaml:"dependencies,omitempty" json:"dependencies,omitempty"`
	// Exclude patterns for files to skip
	Exclude []string `yaml:"exclude,omitempty" json:"exclude,omitempty"`
	// NameOverrides maps definition paths to custom names
	NameOverrides map[string]string `yaml:"nameOverrides,omitempty" json:"nameOverrides,omitempty"`
	// Placement defines default placement constraints for all definitions in this module.
	// Individual definitions can override these constraints.
	Placement *ModulePlacement `yaml:"placement,omitempty" json:"placement,omitempty"`
	// Hooks defines lifecycle hooks for the module
	Hooks *ModuleHooks `yaml:"hooks,omitempty" json:"hooks,omitempty"`
}

ModuleSpec contains module specification

type PlacementCondition

type PlacementCondition struct {
	Key      string   `json:"key"`
	Operator string   `json:"operator"`
	Values   []string `json:"values,omitempty"`
}

PlacementCondition represents a single placement condition.

Jump to

Keyboard shortcuts

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