Documentation
¶
Overview ¶
Package provisioning provides an abstraction layer for infrastructure provisioning through multiple backends.
Index ¶
- Constants
- func AppendJob(jobs []v1alpha1.JobStatus, newJob v1alpha1.JobStatus, maxHistory int) []v1alpha1.JobStatus
- func CheckAPIServerForNonTerminalProvisionJob(ctx context.Context, apiReader client.Reader, key client.ObjectKey, ...) bool
- func ComputeBackoffFromJobs(jobs []v1alpha1.JobStatus, configVersion string) time.Duration
- func ComputeDeprovisionBackoff(jobs []v1alpha1.JobStatus) time.Duration
- func ComputeDesiredConfigVersion(spec any) (string, error)
- func FindJobByID(jobs []v1alpha1.JobStatus, jobID string) *v1alpha1.JobStatus
- func FindLatestJobByType(jobs []v1alpha1.JobStatus, jobType v1alpha1.JobType) *v1alpha1.JobStatus
- func GetJobsFromResource(resource client.Object) []v1alpha1.JobStatus
- func HandleBackoff(ctx context.Context, provState *State, latestJob *v1alpha1.JobStatus, ...) (ctrl.Result, error)
- func HasJobID(job *v1alpha1.JobStatus) bool
- func IsConfigApplied(jobs *[]v1alpha1.JobStatus, desiredConfigVersion string) bool
- func NeedsProvisionJob(latestJob *v1alpha1.JobStatus) bool
- func PollDeprovisionJob(ctx context.Context, provider ProvisioningProvider, resource client.Object, ...) (ctrl.Result, bool, error)
- func PollJob(ctx context.Context, provider ProvisioningProvider, resource client.Object, ...) (ctrl.Result, error)
- func RunDeprovisioningLifecycle(ctx context.Context, provider ProvisioningProvider, resource client.Object, ...) (ctrl.Result, bool, error)
- func RunProvisioningLifecycle(ctx context.Context, provider ProvisioningProvider, resource client.Object, ...) (ctrl.Result, error)
- func TenantStorageClassesFromContext(ctx context.Context) []v1alpha1.ResolvedStorageClass
- func TriggerDeprovisionJob(ctx context.Context, provider ProvisioningProvider, resource client.Object, ...) (ctrl.Result, error)
- func TriggerJob(ctx context.Context, provider ProvisioningProvider, resource client.Object, ...) (ctrl.Result, error)
- func UpdateJob(jobs []v1alpha1.JobStatus, updatedJob v1alpha1.JobStatus) bool
- func WithTenantStorageClasses(ctx context.Context, scs []v1alpha1.ResolvedStorageClass) context.Context
- type AAPClient
- type AAPProvider
- func (p *AAPProvider) GetDeprovisionStatus(ctx context.Context, resource client.Object, jobID string) (ProvisionStatus, error)
- func (p *AAPProvider) GetProvisionStatus(ctx context.Context, resource client.Object, jobID string) (ProvisionStatus, error)
- func (p *AAPProvider) Name() string
- func (p *AAPProvider) TriggerDeprovision(ctx context.Context, resource client.Object) (*DeprovisionResult, error)
- func (p *AAPProvider) TriggerProvision(ctx context.Context, resource client.Object) (*ProvisionResult, error)
- type Action
- type DeprovisionAction
- type DeprovisionResult
- type PollCallbacks
- type ProviderConfig
- type ProvisionResult
- type ProvisionStatus
- type ProvisioningProvider
- type RateLimitError
- type State
Constants ¶
const ( // DefaultStatusPollInterval is the default interval for polling provider status. DefaultStatusPollInterval = 30 * time.Second // DefaultMaxJobHistory is the default number of jobs to keep in status.jobs array. DefaultMaxJobHistory = 10 )
const ( BackoffBaseDelay = 2 * time.Minute BackoffMaxDelay = 30 * time.Minute )
Variables ¶
This section is empty.
Functions ¶
func AppendJob ¶
func AppendJob(jobs []v1alpha1.JobStatus, newJob v1alpha1.JobStatus, maxHistory int) []v1alpha1.JobStatus
AppendJob adds a new job to the jobs array and trims to maxHistory.
func CheckAPIServerForNonTerminalProvisionJob ¶
func CheckAPIServerForNonTerminalProvisionJob(ctx context.Context, apiReader client.Reader, key client.ObjectKey, fresh client.Object) bool
CheckAPIServerForNonTerminalProvisionJob reads the resource directly from the API server and returns true if a non-terminal provision job exists.
func ComputeBackoffFromJobs ¶
ComputeBackoffFromJobs determines the next backoff duration based on the gap between the last two failed provision jobs with the same ConfigVersion.
func ComputeDeprovisionBackoff ¶
ComputeDeprovisionBackoff determines the next backoff duration for deprovision retries.
func ComputeDesiredConfigVersion ¶
ComputeDesiredConfigVersion computes a hash of the spec and returns it. The caller must pass the resource's Spec field (not the entire resource).
func FindJobByID ¶
FindJobByID finds a job by its ID in the jobs array. Returns a pointer to the job if found, nil otherwise.
func FindLatestJobByType ¶
FindLatestJobByType finds the most recent job of the specified type by timestamp. Returns nil if no job of that type exists.
func GetJobsFromResource ¶
GetJobsFromResource extracts the jobs array from a resource. Returns an empty slice for resource types that don't track jobs.
func HandleBackoff ¶
func HandleBackoff(ctx context.Context, provState *State, latestJob *v1alpha1.JobStatus, triggerFn func() (ctrl.Result, error)) (ctrl.Result, error)
HandleBackoff checks if the backoff period has elapsed since the last failed job. If elapsed, it calls triggerFn to retry. Otherwise, it returns a RequeueAfter with the remaining delay.
func IsConfigApplied ¶
IsConfigApplied returns true if the current spec has been successfully applied. Only the latest provision job is considered to avoid false positives when a spec reverts to a previously applied value (A-B-A problem). Also returns true for legacy provision jobs (empty ConfigVersion) that succeeded, to avoid re-triggering provisioning for resources provisioned before ConfigVersion tracking was introduced.
func NeedsProvisionJob ¶
NeedsProvisionJob determines if a new provision job should be triggered. Returns true if no job exists, or if the previous job failed (allowing retry). Used by controllers without config-version-based provisioning (SecurityGroup, Subnet, VirtualNetwork). Controllers with ConfigVersion support should use EvaluateAction instead, which adds backoff and spec-change detection.
func PollDeprovisionJob ¶
func PollDeprovisionJob(ctx context.Context, provider ProvisioningProvider, resource client.Object, jobs *[]v1alpha1.JobStatus, latestDeprovisionJob *v1alpha1.JobStatus, maxHistory int, pollInterval time.Duration) (ctrl.Result, bool, error)
PollDeprovisionJob polls the status of an existing deprovision job. Returns (result, done, error) where done=true means the job reached terminal state and the controller can proceed with finalizer removal. When a deprovision job fails with BlockDeletionOnFailure, the function retries after exponential backoff rather than blocking forever.
func PollJob ¶
func PollJob(ctx context.Context, provider ProvisioningProvider, resource client.Object, provState *State, latestJob *v1alpha1.JobStatus, pollInterval time.Duration, callbacks *PollCallbacks) (ctrl.Result, error)
PollJob checks the status of an existing provision job and updates the jobs slice in place.
func RunDeprovisioningLifecycle ¶
func RunDeprovisioningLifecycle(ctx context.Context, provider ProvisioningProvider, resource client.Object, jobs *[]v1alpha1.JobStatus, maxHistory int, pollInterval time.Duration) (ctrl.Result, bool, error)
RunDeprovisioningLifecycle encapsulates the full deprovisioning flow: trigger if no job exists, poll/retry if one does. Controllers call this instead of duplicating the trigger-or-poll logic. Returns (result, done, error) where done=true means the controller can proceed with finalizer removal.
func RunProvisioningLifecycle ¶
func RunProvisioningLifecycle( ctx context.Context, provider ProvisioningProvider, resource client.Object, provState *State, maxHistory int, pollInterval time.Duration, callbacks *PollCallbacks, checkAPIServer func() bool, statusFlush func() error, ) (ctrl.Result, error)
RunProvisioningLifecycle encapsulates the full provisioning flow: evaluate action, trigger/poll/backoff as needed. Controllers call this instead of duplicating the switch statement. The callbacks customize behavior on success and failure.
statusFlush is called after a provision job is successfully triggered to persist the job status immediately, preventing duplicate jobs from concurrent reconciliations. Errors are logged but non-fatal — the end-of-reconcile status update serves as fallback.
func TenantStorageClassesFromContext ¶
func TenantStorageClassesFromContext(ctx context.Context) []v1alpha1.ResolvedStorageClass
TenantStorageClassesFromContext retrieves the tenant storage classes from the context, or nil if not set.
func TriggerDeprovisionJob ¶
func TriggerDeprovisionJob(ctx context.Context, provider ProvisioningProvider, resource client.Object, jobs *[]v1alpha1.JobStatus, maxHistory int, pollInterval time.Duration) (ctrl.Result, error)
TriggerDeprovisionJob triggers a deprovision job via the provider and handles the result. Updates the jobs slice in place. Returns the result for the controller to return.
func TriggerJob ¶
func TriggerJob(ctx context.Context, provider ProvisioningProvider, resource client.Object, provState *State, maxHistory int, pollInterval time.Duration) (ctrl.Result, error)
TriggerJob triggers a new provision job and updates the jobs slice in place via State.
func UpdateJob ¶
UpdateJob updates an existing job by ID with new values. Returns true if the job was found and updated, false otherwise.
func WithTenantStorageClasses ¶
func WithTenantStorageClasses(ctx context.Context, scs []v1alpha1.ResolvedStorageClass) context.Context
WithTenantStorageClasses returns a context carrying the tenant's resolved storage classes. The AAP provider reads this when building extra_vars.
Types ¶
type AAPClient ¶
type AAPClient interface {
GetTemplate(ctx context.Context, templateName string) (*aap.Template, error)
LaunchJobTemplate(ctx context.Context, req aap.LaunchJobTemplateRequest) (*aap.LaunchJobTemplateResponse, error)
LaunchWorkflowTemplate(ctx context.Context, req aap.LaunchWorkflowTemplateRequest) (*aap.LaunchWorkflowTemplateResponse, error)
GetJob(ctx context.Context, jobID string) (*aap.Job, error)
CancelJob(ctx context.Context, jobID string) error
}
AAPClient is the interface for AAP operations used by the provider.
type AAPProvider ¶
type AAPProvider struct {
// contains filtered or unexported fields
}
AAPProvider implements ProvisioningProvider using direct AAP REST API integration.
Template resolution supports two modes:
- Explicit: provisionTemplate and deprovisionTemplate are set directly
- Prefix-based: templatePrefix is set, and template names are derived from the resource Kind (e.g., prefix "osac" + Kind "VirtualNetwork" → "osac-create-virtual-network")
func NewAAPProvider ¶
func NewAAPProvider(client AAPClient, provisionTemplate, deprovisionTemplate string) *AAPProvider
NewAAPProvider creates a new AAP provider with explicit template names.
func NewAAPProviderWithPrefix ¶
func NewAAPProviderWithPrefix(client AAPClient, templatePrefix string) *AAPProvider
NewAAPProviderWithPrefix creates a new AAP provider that derives template names from the resource Kind using the given prefix. For example, with prefix "osac" and a VirtualNetwork resource, it resolves to "osac-create-virtual-network" and "osac-delete-virtual-network".
func (*AAPProvider) GetDeprovisionStatus ¶
func (p *AAPProvider) GetDeprovisionStatus(ctx context.Context, resource client.Object, jobID string) (ProvisionStatus, error)
GetDeprovisionStatus checks deprovisioning job status via AAP API.
func (*AAPProvider) GetProvisionStatus ¶
func (p *AAPProvider) GetProvisionStatus(ctx context.Context, resource client.Object, jobID string) (ProvisionStatus, error)
GetProvisionStatus checks provisioning job status via AAP API.
func (*AAPProvider) Name ¶
func (p *AAPProvider) Name() string
Name returns the provider name for logging.
func (*AAPProvider) TriggerDeprovision ¶
func (p *AAPProvider) TriggerDeprovision(ctx context.Context, resource client.Object) (*DeprovisionResult, error)
TriggerDeprovision attempts to start deprovisioning for a resource. It checks whether a running provision job needs to be cancelled first.
func (*AAPProvider) TriggerProvision ¶
func (p *AAPProvider) TriggerProvision(ctx context.Context, resource client.Object) (*ProvisionResult, error)
TriggerProvision triggers provisioning via AAP API. Autodetects whether the template is a job_template or workflow_job_template.
type Action ¶
type Action int
Action represents the outcome of shouldTriggerProvision.
func EvaluateAction ¶
EvaluateAction determines the next provisioning action based on job history and config versions.
type DeprovisionAction ¶
type DeprovisionAction string
DeprovisionAction represents the action taken by a provider when attempting to deprovision.
const ( // DeprovisionTriggered means deprovisioning was started and controller should poll status DeprovisionTriggered DeprovisionAction = "triggered" // DeprovisionWaiting means provider is not ready yet and controller should requeue DeprovisionWaiting DeprovisionAction = "waiting" // DeprovisionSkipped means provider determined deprovisioning is not needed DeprovisionSkipped DeprovisionAction = "skipped" )
type DeprovisionResult ¶
type DeprovisionResult struct {
// Action indicates what the provider did
Action DeprovisionAction
// JobID is the tracking identifier when Action==DeprovisionTriggered
// Used by controller to poll status via GetDeprovisionStatus()
// Empty when Action==DeprovisionWaiting or Action==DeprovisionSkipped
JobID string
// BlockDeletionOnFailure indicates whether deletion should be blocked if deprovision fails
// Stored in CR status for crash recovery (controller restart)
// Providers set based on their cleanup guarantees
BlockDeletionOnFailure bool
// ProvisionJobStatus is the current status of the provision job (state and message)
// Populated when provision job is checked before deprovisioning
// This allows the controller to update the CR status to reflect job cancellation/termination
// Empty when no provision job exists
ProvisionJobStatus *ProvisionStatus
}
DeprovisionResult contains the result of attempting to trigger a deprovision operation.
type PollCallbacks ¶
type PollCallbacks struct {
// OnFailed is called when the job transitions to Failed state.
OnFailed func(message string)
// OnSuccess is called when the job succeeds.
OnSuccess func(status ProvisionStatus)
}
PollCallbacks holds optional callbacks for provision job state transitions.
type ProviderConfig ¶
type ProviderConfig struct {
AAPClient AAPClient
ProvisionTemplate string
DeprovisionTemplate string
// TemplatePrefix enables convention-based template name resolution for AAP.
// When set, template names are derived from the resource Kind:
// {prefix}-create-{kind-kebab} and {prefix}-delete-{kind-kebab}
// Explicit ProvisionTemplate/DeprovisionTemplate take precedence when set.
TemplatePrefix string
}
ProviderConfig contains configuration for creating the AAP provisioning provider.
type ProvisionResult ¶
type ProvisionResult struct {
// JobID is the identifier for the triggered job
JobID string
// InitialState is the initial state of the job (typically Pending or Running)
InitialState v1alpha1.JobState
// Message is a human-readable status message
Message string
}
ProvisionResult contains the result of triggering a provision operation.
type ProvisionStatus ¶
type ProvisionStatus struct {
// JobID is the unique identifier for this job.
JobID string
// State indicates the current state of the job.
State v1alpha1.JobState
// Message provides a human-readable status message.
Message string
// Progress indicates completion percentage (0-100).
// Optional: providers that don't support progress tracking should leave this at 0.
Progress int
// StartTime is when the job started execution.
StartTime time.Time
// EndTime is when the job completed (succeeded or failed).
// Zero value indicates job is still running.
EndTime time.Time
// ReconciledVersion is the configuration version that was successfully applied.
// Only populated when State is JobStateSucceeded.
ReconciledVersion string
// ErrorDetails contains detailed error information when State is JobStateFailed.
ErrorDetails string
}
ProvisionStatus represents the current state of a provisioning or deprovisioning job.
func (*ProvisionStatus) MessageWithDetails ¶
func (s *ProvisionStatus) MessageWithDetails() string
MessageWithDetails returns the message with error details appended, if present.
type ProvisioningProvider ¶
type ProvisioningProvider interface {
// TriggerProvision starts provisioning for a resource.
// Returns a ProvisionResult with job details and initial state.
TriggerProvision(ctx context.Context, resource client.Object) (*ProvisionResult, error)
// GetProvisionStatus checks the status of a provisioning job.
// The resource parameter allows providers to check additional state if needed.
GetProvisionStatus(ctx context.Context, resource client.Object, jobID string) (ProvisionStatus, error)
// TriggerDeprovision attempts to deprovision a resource.
// The provider performs any prerequisite checks and returns an action indicating
// whether deprovisioning was triggered, needs to wait, or should be skipped.
TriggerDeprovision(ctx context.Context, resource client.Object) (*DeprovisionResult, error)
// GetDeprovisionStatus checks the status of a deprovisioning job.
GetDeprovisionStatus(ctx context.Context, resource client.Object, jobID string) (ProvisionStatus, error)
// Name returns the provider name for logging and identification.
Name() string
}
ProvisioningProvider abstracts triggering infrastructure automation via AAP and retrieving job status.
func NewProvider ¶
func NewProvider(config ProviderConfig) (ProvisioningProvider, error)
NewProvider creates an AAP provisioning provider from the configuration.
type RateLimitError ¶
RateLimitError indicates a request was rate-limited and should be retried.
func AsRateLimitError ¶
func AsRateLimitError(err error) (*RateLimitError, bool)
AsRateLimitError checks if err is a RateLimitError and returns it.
func (*RateLimitError) Error ¶
func (e *RateLimitError) Error() string