run

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Oct 22, 2024 License: MPL-2.0 Imports: 46 Imported by: 0

Documentation

Overview

Package run is responsible for OTF runs, the primary mechanism for executing terraform

Index

Constants

View Source
const ReporterLockID int64 = 179366396344335597

ReporterLockID is a unique ID guaranteeing only one reporter on a cluster is running at any time.

View Source
const TimeoutLockID int64 = 179366396344335598

TimeoutLockID is a unique ID guaranteeing only one timeout daemon on a cluster is running at any time.

Variables

View Source
var (
	ErrRunDiscardNotAllowed     = errors.New("run was not paused for confirmation or priority; discard not allowed")
	ErrRunCancelNotAllowed      = errors.New("run was not planning or applying; cancel not allowed")
	ErrRunForceCancelNotAllowed = errors.New("run was not planning or applying, has not been canceled non-forcefully, or the cool-off period has not yet passed")
	//
	ErrPhaseAlreadyStarted = errors.New("phase already started")
)
View Source
var ErrInvalidRunStateTransition = errors.New("invalid run state transition")

Functions

func CompilePlanReports added in v0.0.51

func CompilePlanReports(planJSON []byte) (resources Report, outputs Report, err error)

CompilePlanReports compiles reports of planned changes from a JSON representation of a plan file: one report for planned *resources*, and another for planned *outputs*.

func NewCommand added in v0.1.9

func NewCommand(client *otfapi.Client) *cobra.Command

Types

type CLI added in v0.1.9

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

type Change

type Change struct {
	Actions []ChangeAction
}

Change represents the type of change being made

type ChangeAction

type ChangeAction string
const (
	CreateAction ChangeAction = "create"
	UpdateAction ChangeAction = "update"
	DeleteAction ChangeAction = "delete"
)

type Client

type Client struct {
	*otfapi.Client
}

func (*Client) Get added in v0.2.2

func (c *Client) Get(ctx context.Context, runID string) (*Run, error)

func (*Client) GetLockFile

func (c *Client) GetLockFile(ctx context.Context, runID string) ([]byte, error)

func (*Client) GetPlanFile

func (c *Client) GetPlanFile(ctx context.Context, runID string, format PlanFormat) ([]byte, error)

func (*Client) ListRuns

func (c *Client) ListRuns(ctx context.Context, opts ListOptions) (*resource.Page[*Run], error)

func (*Client) UploadLockFile

func (c *Client) UploadLockFile(ctx context.Context, runID string, lockfile []byte) error

func (*Client) UploadPlanFile

func (c *Client) UploadPlanFile(ctx context.Context, runID string, plan []byte, format PlanFormat) error

type ConfigurationVersionService

type ConfigurationVersionService configversion.Service

Alias services so they don't conflict when nested together in struct

type CreateOptions added in v0.1.8

type CreateOptions struct {
	IsDestroy   *bool
	Refresh     *bool
	RefreshOnly *bool
	Message     *string
	// Specifies the configuration version to use for this run. If the
	// configuration version ID is nil, the run will be created using the
	// workspace's latest configuration version.
	ConfigurationVersionID *string
	TargetAddrs            []string
	ReplaceAddrs           []string
	AutoApply              *bool
	Source                 Source
	TerraformVersion       *string
	AllowEmptyApply        *bool
	// PlanOnly specifies if this is a speculative, plan-only run that
	// Terraform cannot apply. Takes precedence over whether the
	// configuration version is marked as speculative or not.
	PlanOnly  *bool
	Variables []Variable
	// contains filtered or unexported fields
}

CreateOptions represents the options for creating a new run. See api.types.RunCreateOptions for documentation on each field.

type ListOptions added in v0.1.8

type ListOptions struct {
	resource.PageOptions
	// Filter by workspace ID
	WorkspaceID *string `schema:"workspace_id,omitempty"`
	// Filter by organization name
	Organization *string `schema:"organization_name,omitempty"`
	// Filter by workspace name
	WorkspaceName *string `schema:"workspace_name,omitempty"`
	// Filter by run statuses (with an implicit OR condition)
	Statuses []Status `schema:"statuses,omitempty"`
	// Filter by plan-only runs
	PlanOnly *bool `schema:"-"`
	// Filter by sources
	Sources []Source
	// Filter by commit SHA that triggered a run
	CommitSHA *string
	// Filter by VCS user's username that triggered a run
	VCSUsername *string
}

ListOptions are options for paginating and filtering a list of runs

type Operation

type Operation string

Run operation specifies the terraform execution mode.

const (
	PlanFormatBinary = "bin"  // plan file in binary format
	PlanFormatJSON   = "json" // plan file in json format

	PlanOnlyOperation     Operation = "plan-only"
	PlanAndApplyOperation Operation = "plan-and-apply"
	DestroyAllOperation   Operation = "destroy-all"
)

type Options

type Options struct {
	WorkspaceAuthorizer internal.Authorizer
	VCSEventSubscriber  vcs.Subscriber

	WorkspaceService     *workspace.Service
	OrganizationService  *organization.Service
	ConfigVersionService *configversion.Service
	ReleasesService      *releases.Service
	VCSProviderService   *vcsprovider.Service
	TokensService        *tokens.Service

	logr.Logger
	internal.Cache
	*sql.DB
	*tfeapi.Responder
	*surl.Signer
	html.Renderer
	*sql.Listener
}

type PeriodReport added in v0.1.17

type PeriodReport struct {
	TotalTime time.Duration  `json:"total_time"`
	Periods   []StatusPeriod `json:"periods"`
}

func (PeriodReport) Percentage added in v0.1.17

func (r PeriodReport) Percentage(i int) float64

type Phase

type Phase struct {
	RunID  string      `json:"run_id"`
	Status PhaseStatus `json:"status"`

	// Timestamps of when a state transition occured. Ordered earliest
	// first.
	StatusTimestamps []PhaseStatusTimestamp `json:"status_timestamps"`

	internal.PhaseType `json:"phase"`

	// report of planned or applied resource changes
	ResourceReport *Report `json:"resource_report"`
	// report of planned or applied output changes
	OutputReport *Report `json:"output_report"`
}

Phase is a section of work performed by a run.

func (*Phase) Done added in v0.1.17

func (p *Phase) Done() bool

func (*Phase) ElapsedTime added in v0.1.17

func (p *Phase) ElapsedTime(now time.Time) time.Duration

ElapsedTime returns the time taken for the phase to complete its running state. If the run is yet to enter a running state then it returns 0. If the running state is still in progress then it returns the time since entering the running state.

func (*Phase) HasChanges

func (p *Phase) HasChanges() bool

func (*Phase) HasStarted added in v0.1.17

func (p *Phase) HasStarted() bool

func (*Phase) StartedAt added in v0.1.17

func (p *Phase) StartedAt() time.Time

StartedAt returns the time the phase started running, returning zero time if it is yet to start running.

func (*Phase) StatusTimestamp

func (p *Phase) StatusTimestamp(status PhaseStatus) (time.Time, error)

StatusTimestamp looks up the timestamp for a status

func (*Phase) String added in v0.1.17

func (p *Phase) String() string

func (*Phase) UpdateStatus

func (p *Phase) UpdateStatus(status PhaseStatus)

type PhaseFinishOptions

type PhaseFinishOptions struct {
	Errored bool `json:"errored,omitempty"`
}

PhaseFinishOptions report the status of a phase upon finishing.

type PhaseStartOptions

type PhaseStartOptions struct {
	Type    string `jsonapi:"primary,phase"`
	AgentID string `jsonapi:"attribute" json:"agent-id,omitempty"`
}

type PhaseStatus

type PhaseStatus string
const (
	PhasePending     PhaseStatus = "pending"
	PhaseQueued      PhaseStatus = "queued"
	PhaseRunning     PhaseStatus = "running"
	PhaseFinished    PhaseStatus = "finished"
	PhaseCanceled    PhaseStatus = "canceled"
	PhaseErrored     PhaseStatus = "errored"
	PhaseUnreachable PhaseStatus = "unreachable"
)

func (PhaseStatus) String

func (s PhaseStatus) String() string

type PhaseStatusTimestamp

type PhaseStatusTimestamp struct {
	Status    PhaseStatus `json:"status"`
	Timestamp time.Time   `json:"timestamp"`
}

type PlanFile

type PlanFile struct {
	ResourceChanges []ResourceChange  `json:"resource_changes"`
	OutputChanges   map[string]Change `json:"output_changes"`
}

PlanFile represents the schema of a plan file

func (*PlanFile) Summarize added in v0.0.51

func (pf *PlanFile) Summarize() (resource, output Report)

Summarize provides a tally of the types of changes proposed in the plan file.

type PlanFileOptions

type PlanFileOptions struct {
	Format PlanFormat `schema:"format,required"`
}

PlanFileOptions are options for the plan file API

type PlanFormat

type PlanFormat string

type Report added in v0.0.51

type Report struct {
	Additions    int `json:"additions"`
	Changes      int `json:"changes"`
	Destructions int `json:"destructions"`
}

Report reports a summary of additions, changes, and deletions of resources in a plan or an apply.

func ParseApplyOutput

func ParseApplyOutput(output string) (Report, error)

func (Report) HasChanges added in v0.0.51

func (r Report) HasChanges() bool

func (Report) String added in v0.0.51

func (r Report) String() string

type Reporter

type Reporter struct {
	logr.Logger
	*internal.HostnameService

	Configs    reporterConfigClient
	Workspaces reporterWorkspaceClient
	VCS        reporterVCSClient
	Runs       reporterRunClient

	// Cache most recently set status for each incomplete run to ensure the
	// same status is not set more than once on an upstream VCS provider.
	// This is important to avoid hitting rate limits on VCS providers, e.g.
	// GitHub has a limit of 1000 status updates on a commit:
	//
	// https://docs.github.com/en/rest/commits/statuses?apiVersion=2022-11-28#create-a-commit-status
	//
	// key is the run ID.
	Cache map[string]vcs.Status
}

Reporter reports back to VCS providers the current status of VCS-triggered runs.

func (*Reporter) Start

func (r *Reporter) Start(ctx context.Context) error

Start starts the reporter daemon. Should be invoked in a go routine.

type ResourceChange

type ResourceChange struct {
	Change Change
}

ResourceChange represents a proposed change to a resource in a plan file

type Run

type Run struct {
	ID                     string                  `jsonapi:"primary,runs"`
	CreatedAt              time.Time               `jsonapi:"attribute" json:"created_at"`
	IsDestroy              bool                    `jsonapi:"attribute" json:"is_destroy"`
	CancelSignaledAt       *time.Time              `jsonapi:"attribute" json:"cancel_signaled_at"`
	Message                string                  `jsonapi:"attribute" json:"message"`
	Organization           string                  `jsonapi:"attribute" json:"organization"`
	Refresh                bool                    `jsonapi:"attribute" json:"refresh"`
	RefreshOnly            bool                    `jsonapi:"attribute" json:"refresh_only"`
	ReplaceAddrs           []string                `jsonapi:"attribute" json:"replace_addrs"`
	PositionInQueue        int                     `jsonapi:"attribute" json:"position_in_queue"`
	TargetAddrs            []string                `jsonapi:"attribute" json:"target_addrs"`
	TerraformVersion       string                  `jsonapi:"attribute" json:"terraform_version"`
	AllowEmptyApply        bool                    `jsonapi:"attribute" json:"allow_empty_apply"`
	AutoApply              bool                    `jsonapi:"attribute" json:"auto_apply"`
	PlanOnly               bool                    `jsonapi:"attribute" json:"plan_only"`
	Source                 Source                  `jsonapi:"attribute" json:"source"`
	Status                 Status                  `jsonapi:"attribute" json:"status"`
	WorkspaceID            string                  `jsonapi:"attribute" json:"workspace_id"`
	ConfigurationVersionID string                  `jsonapi:"attribute" json:"configuration_version_id"`
	ExecutionMode          workspace.ExecutionMode `jsonapi:"attribute" json:"execution_mode"`
	AgentPoolID            *string                 `jsonapi:"attribute" json:"agent_pool_id"`
	Variables              []Variable              `jsonapi:"attribute" json:"variables"`
	Plan                   Phase                   `jsonapi:"attribute" json:"plan"`
	Apply                  Phase                   `jsonapi:"attribute" json:"apply"`

	// Timestamps of when a state transition occured. Ordered earliest
	// first.
	StatusTimestamps []StatusTimestamp `jsonapi:"attribute" json:"status_timestamps"`

	Latest bool `jsonapi:"attribute" json:"latest"` // is latest run for workspace

	// IngressAttributes is non-nil if run was triggered by a VCS event.
	IngressAttributes *configversion.IngressAttributes `jsonapi:"attribute" json:"ingress_attributes"`

	// Username of user who created the run. This is nil if the run was
	// instead triggered by a VCS event.
	CreatedBy *string

	// OTF doesn't support cost estimation but some go-tfe API tests expect
	// a run to enter the RunCostEstimated state, and this boolean
	// determines whether to enter that state upon finishing a plan.
	CostEstimationEnabled bool
}

Run is a terraform run.

func (*Run) CanAccessOrganization

func (r *Run) CanAccessOrganization(action rbac.Action, name string) bool

func (*Run) CanAccessSite

func (*Run) CanAccessSite(action rbac.Action) bool

func (*Run) CanAccessWorkspace

func (r *Run) CanAccessWorkspace(action rbac.Action, policy *internal.WorkspacePolicy) bool

func (*Run) Cancel

func (r *Run) Cancel(isUser, force bool) error

Cancel run. Depending upon whether the run is currently in-progress, the run is either immediately canceled and its status updated to reflect that, or CancelSignaledAt is set to the current time to indicate that a cancelation signal should be sent to the process executing the run.

The isUser arg should be set to true if a user is directly instigating the cancelation; otherwise it should be set to false, i.e. the job service has canceled a job and is now canceling the corresponding run.

The force arg when set to true forceably cancels the run. This is only allowed when an attempt has already been made to cancel the run non-forceably. The force arg is only respected when isUser is true.

func (*Run) Cancelable

func (r *Run) Cancelable() bool

Cancelable determines whether run can be cancelled.

func (*Run) Confirmable

func (r *Run) Confirmable() bool

Confirmable determines whether run can be confirmed.

func (*Run) Discard

func (r *Run) Discard() error

Discard updates the state of a run to reflect it having been discarded.

func (*Run) Discardable

func (r *Run) Discardable() bool

Discardable determines whether run can be discarded.

func (*Run) Done

func (r *Run) Done() bool

Done determines whether run has reached an end state, e.g. applied, discarded, etc.

func (*Run) ElapsedTime added in v0.1.17

func (r *Run) ElapsedTime(now time.Time) time.Duration

ElapsedTime returns the total time the run has taken thus far. If the run has completed, then it is the time taken from entering the pending state (creation) through to completion. Otherwise it is the time since entering the pending state.

func (*Run) EnqueueApply

func (r *Run) EnqueueApply() error

func (*Run) EnqueuePlan

func (r *Run) EnqueuePlan() error

EnqueuePlan enqueues a plan for the run. It also sets the run as the latest run for its workspace (speculative runs are ignored).

func (*Run) Finish

func (r *Run) Finish(phase internal.PhaseType, opts PhaseFinishOptions) (autoapply bool, err error)

Finish updates the run to reflect its plan or apply phase having finished. If a plan phase has finished and an apply should be automatically enqueued then autoapply will be set to true.

func (*Run) ForceCancelAvailableAt

func (r *Run) ForceCancelAvailableAt() *time.Time

ForceCancelAvailableAt provides the time from which point it is permitted to forceably cancel the run. It only possible to do so when an attempt has previously been made to cancel the run non-forceably and a cool-off period has elapsed.

func (*Run) ForceCancelable added in v0.2.0

func (r *Run) ForceCancelable() bool

ForceCancelable determines whether run can be forceably cancelled.

func (*Run) HasChanges

func (r *Run) HasChanges() bool

func (*Run) HasStarted added in v0.1.17

func (r *Run) HasStarted() bool

HasStarted is used by the running_time.tmpl partial template to determine whether to show the "elapsed time" for a run.

func (*Run) InProgress added in v0.2.0

func (r *Run) InProgress() bool

func (*Run) IsAPISource added in v0.1.8

func (r *Run) IsAPISource() bool

func (*Run) IsCLISource added in v0.1.8

func (r *Run) IsCLISource() bool

func (*Run) IsGithubSource added in v0.1.8

func (r *Run) IsGithubSource() bool

func (*Run) IsGitlabSource added in v0.1.8

func (r *Run) IsGitlabSource() bool

func (*Run) IsUISource added in v0.1.8

func (r *Run) IsUISource() bool

func (*Run) PeriodReport added in v0.1.17

func (r *Run) PeriodReport(now time.Time) (report PeriodReport)

PeriodReport provides a report of the duration in which a run has been in each status thus far. Completed statuses such as completed, errored, etc, are ignored because they are an instant not a period of time.

func (*Run) Phase

func (r *Run) Phase() internal.PhaseType

Phase returns the current phase.

func (*Run) Queued

func (r *Run) Queued() bool

func (*Run) Start

func (r *Run) Start() error

Start a run phase

func (*Run) StartedAt added in v0.1.17

func (r *Run) StartedAt() time.Time

StartedAt returns the time the run was created.

func (*Run) StatusTimestamp

func (r *Run) StatusTimestamp(status Status) (time.Time, error)

func (*Run) String added in v0.1.17

func (r *Run) String() string

type Service

type Service struct {
	logr.Logger
	// contains filtered or unexported fields
}

func NewService

func NewService(opts Options) *Service

func (*Service) AddHandlers added in v0.2.2

func (s *Service) AddHandlers(r *mux.Router)

func (*Service) AfterCancelRun added in v0.2.0

func (s *Service) AfterCancelRun(hook func(context.Context, *Run) error)

func (*Service) AfterEnqueueApply added in v0.2.0

func (s *Service) AfterEnqueueApply(hook func(context.Context, *Run) error)

func (*Service) AfterEnqueuePlan added in v0.2.0

func (s *Service) AfterEnqueuePlan(hook func(context.Context, *Run) error)

func (*Service) AfterForceCancelRun added in v0.2.0

func (s *Service) AfterForceCancelRun(hook func(context.Context, *Run) error)

func (*Service) Apply

func (s *Service) Apply(ctx context.Context, runID string) error

Apply enqueues an apply for the run.

func (Service) CanAccess added in v0.2.2

func (a Service) CanAccess(ctx context.Context, action rbac.Action, runID string) (internal.Subject, error)

func (*Service) Cancel

func (s *Service) Cancel(ctx context.Context, runID string) error

func (*Service) Create added in v0.2.2

func (s *Service) Create(ctx context.Context, workspaceID string, opts CreateOptions) (*Run, error)

func (*Service) Delete

func (s *Service) Delete(ctx context.Context, runID string) error

func (*Service) Discard added in v0.2.2

func (s *Service) Discard(ctx context.Context, runID string) error

Discard discards the run.

func (*Service) EnqueuePlan

func (s *Service) EnqueuePlan(ctx context.Context, runID string) (run *Run, err error)

EnqueuePlan enqueues a plan for the run.

NOTE: this is an internal action, invoked by the scheduler only.

func (*Service) FinishPhase

func (s *Service) FinishPhase(ctx context.Context, runID string, phase internal.PhaseType, opts PhaseFinishOptions) (*Run, error)

FinishPhase finishes a phase. Creates a report of changes before updating the status of the run.

func (*Service) ForceCancel added in v0.2.2

func (s *Service) ForceCancel(ctx context.Context, runID string) error

ForceCancel forcefully cancels a run.

func (*Service) Get added in v0.2.2

func (s *Service) Get(ctx context.Context, runID string) (*Run, error)

Get retrieves a run from the db.

func (*Service) GetLockFile added in v0.2.2

func (s *Service) GetLockFile(ctx context.Context, runID string) ([]byte, error)

GetLockFile returns the lock file for the run.

func (*Service) GetPlanFile

func (s *Service) GetPlanFile(ctx context.Context, runID string, format PlanFormat) ([]byte, error)

GetPlanFile returns the plan file for the run.

func (*Service) List added in v0.2.2

func (s *Service) List(ctx context.Context, opts ListOptions) (*resource.Page[*Run], error)

List retrieves multiple runs. Use opts to filter and paginate the list.

func (Service) NewRun added in v0.2.2

func (f Service) NewRun(ctx context.Context, workspaceID string, opts CreateOptions) (*Run, error)

NewRun constructs a new run using the provided options.

func (*Service) StartPhase

func (s *Service) StartPhase(ctx context.Context, runID string, phase internal.PhaseType, _ PhaseStartOptions) (*Run, error)

StartPhase starts a run phase.

func (*Service) UploadLockFile added in v0.2.2

func (s *Service) UploadLockFile(ctx context.Context, runID string, file []byte) error

UploadLockFile persists the lock file for a run.

func (*Service) UploadPlanFile

func (s *Service) UploadPlanFile(ctx context.Context, runID string, plan []byte, format PlanFormat) error

UploadPlanFile persists a run's plan file. The plan format should be either be binary or json.

func (*Service) Watch

func (s *Service) Watch(ctx context.Context) (<-chan pubsub.Event[*Run], func())

type Source added in v0.1.8

type Source string

Source represents a source type of a run.

const (
	SourceAPI       Source = "tfe-api"
	SourceUI        Source = "tfe-ui"
	SourceTerraform Source = "terraform+cloud"
	SourceGithub    Source = "github"
	SourceGitlab    Source = "gitlab"
)

type Spawner

type Spawner struct {
	logr.Logger
	// contains filtered or unexported fields
}

Spawner spawns new runs in response to vcs events

type Status added in v0.1.17

type Status string

Status represents a run state.

const (
	// List all available run statuses supported in OTF.
	RunApplied            Status = "applied"
	RunApplyQueued        Status = "apply_queued"
	RunApplying           Status = "applying"
	RunCanceled           Status = "canceled"
	RunForceCanceled      Status = "force_canceled"
	RunConfirmed          Status = "confirmed"
	RunDiscarded          Status = "discarded"
	RunErrored            Status = "errored"
	RunPending            Status = "pending"
	RunPlanQueued         Status = "plan_queued"
	RunPlanned            Status = "planned"
	RunPlannedAndFinished Status = "planned_and_finished"
	RunPlanning           Status = "planning"

	// OTF doesn't support cost estimation but go-tfe API tests expect this
	// status so it is included expressly to pass the tests.
	RunCostEstimated Status = "cost_estimated"
)

func (Status) String added in v0.1.17

func (r Status) String() string

type StatusPeriod added in v0.1.17

type StatusPeriod struct {
	Status Status        `json:"status"`
	Period time.Duration `json:"period"`
}

StatusPeriod is the duration over which a run has had a status.

type StatusTimestamp added in v0.1.8

type StatusTimestamp struct {
	Status    Status    `json:"status"`
	Timestamp time.Time `json:"timestamp"`
}

type Timeout added in v0.3.0

type Timeout struct {
	logr.Logger

	OverrideCheckInterval time.Duration
	PlanningTimeout       time.Duration
	ApplyingTimeout       time.Duration
	Runs                  timeoutRunClient
}

Timeout is a daemon that "times out" runs if one of the phases - planning, applying - exceeds a timeout. This can happen for a number of reasons, for example a terraform plan or apply is stuck talking to an unresponsive API, or if OTF itself has terminated ungracefully and left runs in a planning or applying state.

func (*Timeout) Start added in v0.3.0

func (e *Timeout) Start(ctx context.Context) error

Start the timeout daemon.

type VCSProviderService

type VCSProviderService vcsprovider.Service

type Variable added in v0.1.8

type Variable struct {
	Key   string
	Value string
}

type WatchOptions

type WatchOptions struct {
	Organization *string `schema:"organization_name,omitempty"` // filter by organization name
	WorkspaceID  *string `schema:"workspace_id,omitempty"`      // filter by workspace ID; mutually exclusive with organization filter
}

WatchOptions filters events returned by the Watch endpoint.

Jump to

Keyboard shortcuts

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