Documentation
¶
Index ¶
- Constants
- Variables
- func BuildResourceInfos(ctx context.Context, deployType common.DeployType, ...) (instResourceInfos []*InstallableResourceInfo, ...)
- func ExecutePlan(parentCtx context.Context, releaseNamespace string, plan *Plan, ...) error
- func InstallableResourceInfoSortByMustInstallHandler(r1, r2 *InstallableResourceInfo) bool
- func InstallableResourceInfoSortByStageHandler(r1, r2 *InstallableResourceInfo) bool
- func OperationID(t OperationType, version OperationVersion, iteration OperationIteration, ...) string
- func OperationIDHuman(t OperationType, iteration OperationIteration, configIDHuman string) string
- func ResourceInstallTypeSortHandler(type1, type2 ResourceInstallType) bool
- func ValidatePlanArtifact(artifact *PlanArtifact, lifetime time.Duration) error
- func ValidateRemote(releaseName, releaseNamespace string, ...) error
- func WritePlanArtifact(ctx context.Context, artifact *PlanArtifact, ...) error
- type BuildFailurePlanOptions
- type BuildPlanOptions
- type BuildResourceInfosOptions
- type DeletableResourceInfo
- type ExecutePlanOptions
- type InstallableResourceInfo
- type LegacyProgressReporter
- type Operation
- type OperationCategory
- type OperationConfig
- type OperationConfigApply
- type OperationConfigCreate
- type OperationConfigCreateRelease
- type OperationConfigDelete
- type OperationConfigDeleteRelease
- type OperationConfigNoop
- type OperationConfigRecreate
- type OperationConfigTrackAbsence
- type OperationConfigTrackPresence
- type OperationConfigTrackReadiness
- type OperationConfigUpdate
- type OperationConfigUpdateRelease
- type OperationIteration
- type OperationStatus
- type OperationType
- type OperationVersion
- type Plan
- func (p *Plan) AddOperationChain() *planChainBuilder
- func (p *Plan) Connect(fromID, toID string) error
- func (p *Plan) MarshalJSON() ([]byte, error)
- func (p *Plan) Operation(id string) (op *Operation, found bool)
- func (p *Plan) Operations() []*Operation
- func (p *Plan) Optimize(noFinalTracking bool) error
- func (p *Plan) SquashOperation(op *Operation)
- func (p *Plan) ToDOT() ([]byte, error)
- func (p *Plan) UnmarshalJSON(data []byte) error
- type PlanArtifact
- type PlanArtifactData
- type PlanArtifactRelease
- type ReleaseInfo
- type ReleaseType
- type ResourceChange
- type ResourceInstallType
Constants ¶
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 )
const ( HiddenInsignificantChanges = "<hidden insignificant changes>" HiddenSensitiveChanges = "<hidden sensitive changes>" HiddenVerboseCRDChanges = "<hidden verbose CRD changes>" HiddenVerboseChanges = "<hidden verbose changes>" )
const PlanArtifactSchemeVersion = "v1"
Variables ¶
var OrderedResourceInstallTypes = []ResourceInstallType{ ResourceInstallTypeNone, ResourceInstallTypeCreate, ResourceInstallTypeRecreate, ResourceInstallTypeUpdate, ResourceInstallTypeApply, }
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 ValidatePlanArtifact ¶
func ValidatePlanArtifact(artifact *PlanArtifact, lifetime time.Duration) error
func ValidateRemote ¶
func ValidateRemote(releaseName, releaseNamespace string, installableResourceInfos []*InstallableResourceInfo, forceAdoption bool) error
Should only be called if cluster access is allowed.
func WritePlanArtifact ¶
func WritePlanArtifact(ctx context.Context, artifact *PlanArtifact, path, secretKey, secretWorkDir string) error
Types ¶
type BuildFailurePlanOptions ¶
type BuildFailurePlanOptions struct {
NoFinalTracking bool
}
type BuildPlanOptions ¶
type BuildPlanOptions struct {
NoFinalTracking bool
}
type BuildResourceInfosOptions ¶
type BuildResourceInfosOptions struct {
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
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"`
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) Stop ¶
func (r *LegacyProgressReporter) Stop(ctx context.Context)
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) UnmarshalJSON ¶
type OperationCategory ¶
type OperationCategory string
type OperationConfig ¶
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 *helmrelease.Release `json:"release"`
}
func (*OperationConfigCreateRelease) ID ¶
func (c *OperationConfigCreateRelease) ID() string
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 (c *OperationConfigDeleteRelease) ID() string
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 (c *OperationConfigRecreate) ID() string
func (*OperationConfigRecreate) IDHuman ¶
func (c *OperationConfigRecreate) IDHuman() string
type OperationConfigTrackAbsence ¶
type OperationConfigTrackAbsence struct {
ResourceMeta *spec.ResourceMeta `json:"resourceMeta"`
}
func (*OperationConfigTrackAbsence) ID ¶
func (c *OperationConfigTrackAbsence) ID() string
func (*OperationConfigTrackAbsence) IDHuman ¶
func (c *OperationConfigTrackAbsence) IDHuman() string
type OperationConfigTrackPresence ¶
type OperationConfigTrackPresence struct {
ResourceMeta *spec.ResourceMeta `json:"resourceMeta"`
}
func (*OperationConfigTrackPresence) ID ¶
func (c *OperationConfigTrackPresence) ID() string
func (*OperationConfigTrackPresence) IDHuman ¶
func (c *OperationConfigTrackPresence) IDHuman() string
type OperationConfigTrackReadiness ¶
type OperationConfigTrackReadiness struct {
ResourceMeta *spec.ResourceMeta `json:"resourceMeta"`
FailMode multitrack.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 (c *OperationConfigTrackReadiness) ID() string
func (*OperationConfigTrackReadiness) IDHuman ¶
func (c *OperationConfigTrackReadiness) IDHuman() string
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 *helmrelease.Release `json:"release"`
}
func (*OperationConfigUpdateRelease) ID ¶
func (c *OperationConfigUpdateRelease) ID() string
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 ¶
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(installableInfos []*InstallableResourceInfo, deletableInfos []*DeletableResourceInfo, releaseInfos []*ReleaseInfo, 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 (*Plan) AddOperationChain ¶
func (p *Plan) AddOperationChain() *planChainBuilder
func (*Plan) MarshalJSON ¶
func (*Plan) Operations ¶
func (*Plan) SquashOperation ¶
func (*Plan) UnmarshalJSON ¶
type PlanArtifact ¶
type PlanArtifact struct {
APIVersion string `json:"apiVersion"`
Data *PlanArtifactData `json:"-"`
DataRaw string `json:"dataRaw"`
DeployType common.DeployType `json:"deployType"`
Encrypted bool `json:"encrypted"`
Release PlanArtifactRelease `json:"release"`
Timestamp time.Time `json:"timestamp"`
}
func ReadPlanArtifact ¶
func ReadPlanArtifact(ctx context.Context, path, secretKey, secretWorkDir string) (*PlanArtifact, error)
type PlanArtifactData ¶
type PlanArtifactData struct {
Options common.ReleaseInstallRuntimeOptions `json:"options"`
Changes []*ResourceChange `json:"changes"`
Plan *Plan `json:"plan"`
Release *release.Release `json:"release"`
InstallableResourceInfos []*InstallableResourceInfo `json:"installableResourceInfos"`
ReleaseInfos []*ReleaseInfo `json:"releaseInfos"`
}
type PlanArtifactRelease ¶
type ReleaseInfo ¶
type ReleaseInfo struct {
Release *helmrelease.Release `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 []*helmrelease.Release, newRel *helmrelease.Release) ([]*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.
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 ¶
func (c *ResourceChange) UDiff(opts common.ResourceDiffOptions) (string, error)
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" )