plan

package
v2.0.0-alpha.1 Latest Latest
Warning

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

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

Documentation

Index

Constants

View Source
const (
	// Does nothing. Used for things like  grouping.
	OperationCategoryMeta OperationCategory = "meta"
	// Operations that mutate Kubernetes resources in the cluster.
	OperationCategoryResource OperationCategory = "resource"
	// Operations that track resources in the cluster. Never mutate anything.
	OperationCategoryTrack OperationCategory = "track"
	// Operations that mutate Helm releases in the cluster.
	OperationCategoryRelease OperationCategory = "release"

	OperationStatusUnknown   OperationStatus = ""
	OperationStatusPending   OperationStatus = "pending"
	OperationStatusCompleted OperationStatus = "completed"
	OperationStatusFailed    OperationStatus = "failed"

	OperationTypeApply          OperationType = "apply"
	OperationTypeCreate         OperationType = "create"
	OperationTypeCreateRelease  OperationType = "create-release"
	OperationTypeDelete         OperationType = "delete"
	OperationTypeDeleteRelease  OperationType = "delete-release"
	OperationTypeNoop           OperationType = "noop"
	OperationTypeRecreate       OperationType = "recreate"
	OperationTypeTrackAbsence   OperationType = "track-absence"
	OperationTypeTrackPresence  OperationType = "track-presence"
	OperationTypeTrackReadiness OperationType = "track-readiness"
	OperationTypeUpdate         OperationType = "update"
	OperationTypeUpdateRelease  OperationType = "update-release"

	OperationVersionApply          OperationVersion = 1
	OperationVersionCreate         OperationVersion = 1
	OperationVersionCreateRelease  OperationVersion = 1
	OperationVersionDelete         OperationVersion = 1
	OperationVersionDeleteRelease  OperationVersion = 1
	OperationVersionNoop           OperationVersion = 1
	OperationVersionRecreate       OperationVersion = 1
	OperationVersionTrackAbsence   OperationVersion = 1
	OperationVersionTrackPresence  OperationVersion = 1
	OperationVersionTrackReadiness OperationVersion = 1
	OperationVersionUpdate         OperationVersion = 1
	OperationVersionUpdateRelease  OperationVersion = 1
)
View Source
const (
	HiddenInsignificantChanges = "<hidden insignificant changes>"
	HiddenVerboseCRDChanges    = "<hidden verbose CRD changes>"
)

Variables

Functions

func BuildResourceInfos

func BuildResourceInfos(ctx context.Context, deployType common.DeployType, releaseName, releaseNamespace string, instResources []*resource.InstallableResource, delResources []*resource.DeletableResource, prevReleaseFailed bool, clientFactory kube.ClientFactorier, opts BuildResourceInfosOptions) (instResourceInfos []*InstallableResourceInfo, delResourceInfos []*DeletableResourceInfo, err error)

From Installable/DeletableResource builds Installable/DeletableResourceInfo. If you can do something earlier than in BuildReleaseInfos - do it there. Here you can access the cluster to get more info, and here we actually decide what to do with each resource. Initially all this logic was in BuildPlan, but it became way too complex, so we extracted it here.

func ExecutePlan

func ExecutePlan(parentCtx context.Context, releaseNamespace string, plan *Plan, taskStore *kdutil.Concurrent[*statestore.TaskStore], logStore *kdutil.Concurrent[*logstore.LogStore], informerFactory *kdutil.Concurrent[*informer.InformerFactory], history release.Historier, clientFactory kube.ClientFactorier, opts ExecutePlanOptions) error

Executes the given plan. It doesn't care what kind of plan it is (install, upgrade, failure plan, etc.). All the differences between these plans must be figured out earlier, e.g. in BuildPlan. This generic design must be preserved. Keep it simple: if something can be done on earlier stages, do it there.

func InstallableResourceInfoSortByMustInstallHandler

func InstallableResourceInfoSortByMustInstallHandler(r1, r2 *InstallableResourceInfo) bool

func InstallableResourceInfoSortByStageHandler

func InstallableResourceInfoSortByStageHandler(r1, r2 *InstallableResourceInfo) bool

func OperationID

func OperationID(t OperationType, version OperationVersion, iteration OperationIteration, configID string) string

func OperationIDHuman

func OperationIDHuman(t OperationType, iteration OperationIteration, configIDHuman string) string

func ResourceInstallTypeSortHandler

func ResourceInstallTypeSortHandler(type1, type2 ResourceInstallType) bool

func ValidateRemote

func ValidateRemote(releaseName, releaseNamespace string, installableResourceInfos []*InstallableResourceInfo, forceAdoption bool) error

Should only be called if cluster access is allowed.

Types

type BuildFailurePlanOptions

type BuildFailurePlanOptions struct {
	NoFinalTracking bool
}

type BuildPlanOptions

type BuildPlanOptions struct {
	NoFinalTracking bool
}

type BuildResourceInfosOptions

type BuildResourceInfosOptions struct {
	DiffPatches                        []*spec.CompiledPatch
	ExtraRuntimeAnnotations            map[string]string
	ExtraRuntimeLabels                 map[string]string
	LastDeployedOrLastRelResourceSpecs []*spec.ResourceSpec
	NetworkParallelism                 int
	NoRemoveManualChanges              bool
}

type DeletableResourceInfo

type DeletableResourceInfo struct {
	*spec.ResourceMeta

	GetResult        *unstructured.Unstructured
	LocalResource    *resource.DeletableResource
	MustDelete       bool
	MustTrackAbsence bool
	Stage            common.Stage
}

A data class, which stores all info to make a decision on what to do with the to-be-deleted resource in the plan.

type ExecutePlanOptions

type ExecutePlanOptions struct {
	common.TrackingOptions

	InstallableResourceInfos []*InstallableResourceInfo
	LegacyProgressReporter   *LegacyProgressReporter
	NetworkParallelism       int
}

type InstallableResourceInfo

type InstallableResourceInfo struct {
	*spec.ResourceMeta `json:"resourceMeta"`

	LocalResource  *resource.InstallableResource `json:"localResource"`
	GetResult      *unstructured.Unstructured    `json:"getResult"`
	DryApplyResult *unstructured.Unstructured    `json:"dryApplyResult"`
	DryApplyErr    error                         `json:"dryApplyErr"`

	MustInstall                   ResourceInstallType `json:"mustInstall"`
	MustDeleteOnSuccessfulInstall bool                `json:"mustDeleteOnSuccessfulInstall"`
	MustDeleteOnFailedInstall     bool                `json:"mustDeleteOnFailedInstall"`
	MustTrackReadiness            bool                `json:"mustTrackReadiness"`
	FailMode                      statestore.FailMode `json:"failMode"`

	Stage                          common.Stage `json:"stage"`
	StageDeleteOnSuccessfulInstall common.Stage `json:"stageDeleteOnSuccessfulInstall,omitempty"`
	Iteration                      int          `json:"iteration"`
}

A data class, which stores all info to make a decision on what to do with the to-be-installed resource in the plan.

type LegacyProgressReporter

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

func NewLegacyProgressReporter

func NewLegacyProgressReporter(reportCh chan<- progrep.ProgressReport) *LegacyProgressReporter

func (*LegacyProgressReporter) ReportStatus

func (r *LegacyProgressReporter) ReportStatus(opID string, status progrep.OperationStatus)

func (*LegacyProgressReporter) StartPlan

func (r *LegacyProgressReporter) StartPlan(p *Plan, releaseNamespace string, installableResourceInfos []*InstallableResourceInfo, mapper meta.RESTMapper, opts StartPlanOptions)

StartPlan appends the operations of the plan that is about to be executed to the report and makes them addressable by ReportStatus. Operations of the previously started plans stay in the report as they are. The plans are chained: the root operations of the new plan depend on the final operations of the previous one, so the whole run reads as a single graph. Operations of the previous plan that never started are marked Canceled. Untouched resources are reported for the first plan only: later plans act upon a release the first plan has already described in full.

func (*LegacyProgressReporter) Stop

func (r *LegacyProgressReporter) Stop(ctx context.Context)

Stop sends the final report with a blocking send. Operations that never started are marked Canceled first: nothing is going to run them anymore.

type Operation

type Operation struct {
	Type      OperationType      `json:"type"`
	Version   OperationVersion   `json:"version"`
	Category  OperationCategory  `json:"category"`
	Iteration OperationIteration `json:"iteration"`
	Status    OperationStatus    `json:"status"`
	Config    OperationConfig    `json:"config"`
}

Represents an operation on a resource, such as create, update, track readiness, etc. The operation ID must be unique: you can't have two operations with the same ID in the plan/graph. Operation must be easily serializable.

func (*Operation) ID

func (o *Operation) ID() string

func (*Operation) IDHuman

func (o *Operation) IDHuman() string

func (*Operation) UnmarshalJSON

func (o *Operation) UnmarshalJSON(data []byte) error

type OperationCategory

type OperationCategory string

type OperationConfig

type OperationConfig interface {
	ID() string
	IDHuman() string
}

Any config that is needed to execute the operation goes here, as long as it doesn't fit into other fields of the Operation struct. The underlying struct can have any number of fields of any kind, just make sure they are easily serializable.

type OperationConfigApply

type OperationConfigApply struct {
	ResourceSpec *spec.ResourceSpec `json:"resourceSpec"`
}

func (*OperationConfigApply) ID

func (c *OperationConfigApply) ID() string

func (*OperationConfigApply) IDHuman

func (c *OperationConfigApply) IDHuman() string

type OperationConfigCreate

type OperationConfigCreate struct {
	ResourceSpec  *spec.ResourceSpec `json:"resourceSpec"`
	ForceReplicas *int               `json:"forceReplicas,omitempty"`
}

func (*OperationConfigCreate) ID

func (c *OperationConfigCreate) ID() string

func (*OperationConfigCreate) IDHuman

func (c *OperationConfigCreate) IDHuman() string

type OperationConfigCreateRelease

type OperationConfigCreateRelease struct {
	Release *release.VersionedRelease `json:"release"`
}

func (*OperationConfigCreateRelease) ID

func (*OperationConfigCreateRelease) IDHuman

func (c *OperationConfigCreateRelease) IDHuman() string

type OperationConfigDelete

type OperationConfigDelete struct {
	ResourceMeta      *spec.ResourceMeta         `json:"resourceMeta"`
	DeletePropagation metav1.DeletionPropagation `json:"deletePropagation"`
}

func (*OperationConfigDelete) ID

func (c *OperationConfigDelete) ID() string

func (*OperationConfigDelete) IDHuman

func (c *OperationConfigDelete) IDHuman() string

type OperationConfigDeleteRelease

type OperationConfigDeleteRelease struct {
	ReleaseName      string `json:"releaseName"`
	ReleaseNamespace string `json:"releaseNamespace"`
	ReleaseRevision  int    `json:"releaseRevision"`
}

func (*OperationConfigDeleteRelease) ID

func (*OperationConfigDeleteRelease) IDHuman

func (c *OperationConfigDeleteRelease) IDHuman() string

type OperationConfigNoop

type OperationConfigNoop struct {
	OpID string `json:"opID"`
}

func (*OperationConfigNoop) ID

func (c *OperationConfigNoop) ID() string

func (*OperationConfigNoop) IDHuman

func (c *OperationConfigNoop) IDHuman() string

type OperationConfigRecreate

type OperationConfigRecreate struct {
	ResourceSpec      *spec.ResourceSpec         `json:"resourceSpec"`
	DeletePropagation metav1.DeletionPropagation `json:"deletePropagation"`
	ForceReplicas     *int                       `json:"forceReplicas,omitempty"`
}

func (*OperationConfigRecreate) ID

func (*OperationConfigRecreate) IDHuman

func (c *OperationConfigRecreate) IDHuman() string

type OperationConfigTrackAbsence

type OperationConfigTrackAbsence struct {
	ResourceMeta *spec.ResourceMeta `json:"resourceMeta"`
}

func (*OperationConfigTrackAbsence) ID

func (*OperationConfigTrackAbsence) IDHuman

func (c *OperationConfigTrackAbsence) IDHuman() string

type OperationConfigTrackPresence

type OperationConfigTrackPresence struct {
	ResourceMeta *spec.ResourceMeta `json:"resourceMeta"`
}

func (*OperationConfigTrackPresence) ID

func (*OperationConfigTrackPresence) IDHuman

func (c *OperationConfigTrackPresence) IDHuman() string

type OperationConfigTrackReadiness

type OperationConfigTrackReadiness struct {
	ResourceMeta *spec.ResourceMeta `json:"resourceMeta"`

	FailMode                                 statestore.FailMode       `json:"failMode"`
	FailuresAllowed                          int                       `json:"failuresAllowed"`
	IgnoreLogs                               bool                      `json:"ignoreLogs"`
	IgnoreLogsForContainers                  []string                  `json:"ignoreLogsForContainers,omitempty"`
	IgnoreLogsByRegex                        *regexp.Regexp            `json:"ignoreLogsByRegex"`
	IgnoreLogsByRegexForContainers           map[string]*regexp.Regexp `json:"ignoreLogsByRegexForContainers"`
	IgnoreReadinessProbeFailsByContainerName map[string]time.Duration  `json:"ignoreReadinessProbeFailsByContainerName,omitempty"`
	NoActivityTimeout                        time.Duration             `json:"noActivityTimeout"`
	SaveEvents                               bool                      `json:"saveEvents"`
	SaveLogsByRegex                          *regexp.Regexp            `json:"saveLogsByRegex"`
	SaveLogsByRegexForContainers             map[string]*regexp.Regexp `json:"saveLogsByRegexForContainers"`
	SaveLogsOnlyForContainers                []string                  `json:"saveLogsOnlyForContainers,omitempty"`
	SaveLogsOnlyForNumberOfReplicas          int                       `json:"saveLogsOnlyForNumberOfReplicas"`
}

func (*OperationConfigTrackReadiness) ID

func (*OperationConfigTrackReadiness) IDHuman

type OperationConfigUpdate

type OperationConfigUpdate struct {
	ResourceSpec *spec.ResourceSpec `json:"resourceSpec"`
}

func (*OperationConfigUpdate) ID

func (c *OperationConfigUpdate) ID() string

func (*OperationConfigUpdate) IDHuman

func (c *OperationConfigUpdate) IDHuman() string

type OperationConfigUpdateRelease

type OperationConfigUpdateRelease struct {
	Release *release.VersionedRelease `json:"release"`
}

func (*OperationConfigUpdateRelease) ID

func (*OperationConfigUpdateRelease) IDHuman

func (c *OperationConfigUpdateRelease) IDHuman() string

type OperationIteration

type OperationIteration int

Helps to avoid operation ID collisions. Since you can't have two operations with the same ID in the graph, you can increment the iteration to get a new unique ID for the operation. The higher the iteration, the later in the plan/graph the operation should appear.

type OperationStatus

type OperationStatus string

type OperationType

type OperationType string

type OperationVersion

type OperationVersion int

Used to handle breaking changes in the Operation struct.

type Plan

type Plan struct {
	Graph graph.Graph[string, *Operation]
}

Wrapper over dominikbraun/graph to make it easier to use as a plan/graph of operations.

func BuildFailurePlan

func BuildFailurePlan(failedPlan *Plan, installableInfos []*InstallableResourceInfo, releaseInfos []*ReleaseInfo, opts BuildFailurePlanOptions) (*Plan, error)

When the main plan fails, the failure plan must be built and executed.

func BuildPlan

func BuildPlan(ctx context.Context, installableInfos []*InstallableResourceInfo, deletableInfos []*DeletableResourceInfo, releaseInfos []*ReleaseInfo, releaseNamespace string, opts BuildPlanOptions) (*Plan, error)

Builds any kind of a plan, be it for install, upgrade, rollback or uninstall. The only exception is a failure plan (see BuildFailurePlan), because it's way too different. Any differences between different kinds of plans must be figured out earlier, e.g. at BuildResourceInfos level. This generic design must be preserved. Keep it simple: if something can be done on earlier stages, do it there.

func NewPlan

func NewPlan() *Plan

func (*Plan) AddOperationChain

func (p *Plan) AddOperationChain() *planChainBuilder

func (*Plan) Connect

func (p *Plan) Connect(fromID, toID string) error

func (*Plan) MarshalJSON

func (p *Plan) MarshalJSON() ([]byte, error)

func (*Plan) Operation

func (p *Plan) Operation(id string) (op *Operation, found bool)

func (*Plan) Operations

func (p *Plan) Operations() []*Operation

func (*Plan) Optimize

func (p *Plan) Optimize(noFinalTracking bool) error

func (*Plan) SquashOperation

func (p *Plan) SquashOperation(op *Operation)

func (*Plan) ToDOT

func (p *Plan) ToDOT() ([]byte, error)

func (*Plan) UnmarshalJSON

func (p *Plan) UnmarshalJSON(data []byte) error

type ReleaseInfo

type ReleaseInfo struct {
	Revision release.Revision          `json:"revision"`
	Release  *release.VersionedRelease `json:"release"`

	Must                   ReleaseType `json:"must"`
	MustFailOnFailedDeploy bool        `json:"mustFailOnFailedDeploy"`
}

Data class, which stores all info to make a decision on what to do with the release revision in the plan.

func BuildReleaseInfos

func BuildReleaseInfos(ctx context.Context, deployType common.DeployType, prevReleases []helmrel.Accessor, newRel helmrel.Accessor) ([]*ReleaseInfo, error)

Build ReleaseInfos from Releases that we got from the cluster. Here we actually decide on what to do with each release revision. Compute here as much as you can: Release shouldn't be used for decision making (its just a JSON representation of a Helm release) and BuildPlan is complex enough already.

func BuildUninstallReleaseInfos

func BuildUninstallReleaseInfos(ctx context.Context, revisions []release.Revision, lastRel helmrel.Accessor) ([]*ReleaseInfo, error)

Build ReleaseInfos for an uninstall. Only the last revision needs a release body, since it is the only one whose status is rewritten; older revisions are dropped by name and version alone.

type ReleaseType

type ReleaseType string
const (
	// No-op
	ReleaseTypeNone ReleaseType = "none"
	// First release revision is to be installed
	ReleaseTypeInstall ReleaseType = "install"
	// New release revision is to be installed as an upgrade over the previous one
	ReleaseTypeUpgrade ReleaseType = "upgrade"
	// New release revision is to be installed, based on one of the previous revisions
	ReleaseTypeRollback ReleaseType = "rollback"
	// One of the previous revisions is to be superseded by a successful release
	ReleaseTypeSupersede ReleaseType = "supersede"
	// Release is to be uninstalled as a whole, with its resources
	ReleaseTypeUninstall ReleaseType = "uninstall"
	// Release revision is to be dropped/deleted (its resources are untouched)
	ReleaseTypeDelete ReleaseType = "delete"
)

type ResourceChange

type ResourceChange struct {
	// Any operations on the resource after the initial one.
	ExtraOperations []string `json:"extraOperations"`
	// The reason for the change.
	Reason       string                     `json:"reason"`
	ResourceMeta *spec.ResourceMeta         `json:"resourceMeta"`
	Type         string                     `json:"type"`
	TypeStyle    color.Style                `json:"typeStyle"`
	Before       *unstructured.Unstructured `json:"before"`
	After        *unstructured.Unstructured `json:"after"`
}

func CalculatePlannedChanges

func CalculatePlannedChanges(installableInfos []*InstallableResourceInfo, deletableInfos []*DeletableResourceInfo) ([]*ResourceChange, error)

Calculate planned changes for informational purposes. Doesn't need the full plan, just having Installable/DeletableResourceInfos is enough. Returns the structured result and shouldn't decide on how to present this data.

func (*ResourceChange) UDiff

type ResourceInstallType

type ResourceInstallType string
const (
	ResourceInstallTypeNone     ResourceInstallType = "none"
	ResourceInstallTypeCreate   ResourceInstallType = "create"
	ResourceInstallTypeRecreate ResourceInstallType = "recreate"
	ResourceInstallTypeUpdate   ResourceInstallType = "update"
	// When we can't figure out whether to create or update the resource, we blindly apply it
	ResourceInstallTypeApply ResourceInstallType = "apply"
)

type StartPlanOptions

type StartPlanOptions struct {
	// UntouchedResourcesOnly, when true, omits the plan's own operations and reports the untouched
	// resources alone. Set it for a plan that is not going to be executed: its operations would
	// otherwise stay Pending forever.
	UntouchedResourcesOnly bool
}

Jump to

Keyboard shortcuts

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