Documentation
¶
Overview ¶
Package pluginimport mirrors plugin versions from upstream releases into an organization's plugin registry (ADR-0027 A1).
Index ¶
- Constants
- Variables
- func HashiCorpKeyring() (openpgp.EntityList, error)
- func NewHTTPClient() *http.Client
- func NextPrune(schedule string, now time.Time) (time.Time, error)
- func PruneOnce(ctx context.Context, prunes Pruning, emitter *audit.SystemEmitter, ...) (int, error)
- func ValidProduct(product string) bool
- func ValidPruneAge(days int) bool
- func ValidRepository(repository string) bool
- type BundleExports
- type BundleImporter
- type BundleImports
- type BundleVersionOutcome
- type Catalogue
- type Checker
- type Exporter
- type GitHub
- type GitHubRelease
- type Importer
- func (i *Importer) ImportGitHubVersion(ctx context.Context, tenant store.OrganizationTenant, repository, tag string, ...) VersionOutcome
- func (i *Importer) ImportVersion(ctx context.Context, tenant store.OrganizationTenant, product, version string, ...) VersionOutcome
- func (i *Importer) Sync(ctx context.Context, tenant store.OrganizationTenant, name string, ...) VersionOutcome
- type Jobs
- type PlatformOutcome
- type Pruner
- type Prunes
- type Pruning
- type Repository
- type UpdateChecks
- type Upstream
- type UpstreamVersion
- type VersionOutcome
- type Worker
Constants ¶
const ( BundleOutcomeImported = "imported" BundleOutcomeSkipped = "skipped" BundleOutcomeMismatch = "mismatch" BundleOutcomeRefused = "refused" )
The outcomes of one bundled version (ADR-0029 D4, D5).
const ( OutcomeImported = "imported" OutcomeAlreadyMirrored = "already_mirrored" OutcomeRevoked = "revoked" OutcomeRestored = "restored" OutcomeFailed = "failed" )
Outcomes recorded per version and per platform of an import.
const ( StateRunning = "running" StateSucceeded = "succeeded" StatePartiallySucceeded = "partially_succeeded" StateFailed = "failed" )
Job states, as the platform API reports them.
Variables ¶
var ErrGitHubRateLimited = errors.New("GitHub rate limit reached")
ErrGitHubRateLimited is GitHub refusing an unauthenticated caller that has spent its hourly allowance (60 calls per egress address).
var ErrNotAReleaseLink = errors.New("not a release link of a packer-plugin repository")
ErrNotAReleaseLink is a link that names no packer-plugin release.
var ErrUpstreamNotFound = errors.New("not found upstream")
ErrUpstreamNotFound is an upstream answer that the product or version does not exist.
ErrUpstreamUnavailable is an upstream that could not be reached or answered with a server error; it is distinct from an answer that something is absent.
var PruneAges = []int{1, 7, 14, 30, 60, 90, 180, 365}
PruneAges are the age limits the console offers, in days.
Functions ¶
func HashiCorpKeyring ¶
func HashiCorpKeyring() (openpgp.EntityList, error)
HashiCorpKeyring returns the pinned HashiCorp release-signing key.
func NewHTTPClient ¶
NewHTTPClient is the client imports and catalogue reads share. It has no overall timeout, because a zip download may legitimately take minutes.
func PruneOnce ¶
func PruneOnce(ctx context.Context, prunes Pruning, emitter *audit.SystemEmitter, tenant store.OrganizationTenant, ageDays int, now time.Time) (int, error)
PruneOnce clears the organization's finished jobs older than ageDays and writes the audit pair for the run; the API's Prune now shares it.
func ValidProduct ¶
ValidProduct reports whether product names a Packer plugin on releases.hashicorp.com.
func ValidPruneAge ¶
ValidPruneAge reports whether days is one of the offered limits.
func ValidRepository ¶
ValidRepository reports whether repository is owner/packer-plugin-<name>.
Types ¶
type BundleExports ¶
type BundleExports interface {
ClaimPluginBundle(context.Context, time.Duration) (*store.ClaimedPluginBundle, error)
ExportablePluginVersions(context.Context, store.OrganizationTenant) ([]store.ExportablePlugin, error)
OpenPluginObject(context.Context, string) (io.ReadCloser, error)
PutPluginBundle(context.Context, store.OrganizationTenant, string, io.ReadSeeker, int64) error
DeletePluginBundleObject(context.Context, store.OrganizationTenant, string) error
RecordPluginBundle(context.Context, store.OrganizationTenant, *store.PluginBundleResult, string) error
}
BundleExports is where the exporter finds content and stores archives.
type BundleImporter ¶
type BundleImporter struct {
// contains filtered or unexported fields
}
BundleImporter ingests uploaded plugin bundles.
func NewBundleImporter ¶
func NewBundleImporter(imports BundleImports, keyring openpgp.EntityList, emitter *audit.SystemEmitter, interval time.Duration, logger *slog.Logger) *BundleImporter
NewBundleImporter polls queued bundle imports.
func (*BundleImporter) Run ¶
func (b *BundleImporter) Run(ctx context.Context)
Run works queued imports until ctx ends.
type BundleImports ¶
type BundleImports interface {
ClaimPluginBundleImport(context.Context, time.Duration) (*store.ClaimedPluginBundleImport, error)
RecordPluginBundleImport(context.Context, store.OrganizationTenant, string, store.PluginBundleOrigin, any, string) error
OpenPluginObject(context.Context, string) (io.ReadCloser, error)
DeletePluginBundleObject(context.Context, store.OrganizationTenant, string) error
PluginVersionSumsDigest(context.Context, store.OrganizationTenant, string, string) (string, error)
PublishPluginVersion(context.Context, store.OrganizationTenant, store.PluginVersionInput) error
}
BundleImports is where the importer finds uploaded bundles and publishes their versions.
type BundleVersionOutcome ¶
type BundleVersionOutcome struct {
Plugin string `json:"plugin"`
Version string `json:"version"`
OriginKind string `json:"origin_kind"`
OriginRepository string `json:"origin_repository,omitempty"`
Outcome string `json:"outcome"`
Error string `json:"error,omitempty"`
}
BundleVersionOutcome is one bundled version's result, with where the bundle said it came from.
type Catalogue ¶
Catalogue is what the import screens read: HashiCorp's release service and GitHub releases.
type Checker ¶
type Checker struct {
// contains filtered or unexported fields
}
Checker asks each opted-in plugin's source for its newest stable release (ADR-0027 A6). It never imports.
func NewChecker ¶
func NewChecker(checks UpdateChecks, upstream *Upstream, github *GitHub, interval time.Duration, logger *slog.Logger) *Checker
NewChecker checks each opted-in plugin once per interval.
type Exporter ¶
type Exporter struct {
DufflebagVersion string
// contains filtered or unexported fields
}
Exporter builds queued plugin bundles.
func NewExporter ¶
func NewExporter(exports BundleExports, emitter *audit.SystemEmitter, interval time.Duration, logger *slog.Logger) *Exporter
NewExporter polls queued bundle exports.
type GitHub ¶
type GitHub struct {
// contains filtered or unexported fields
}
GitHub reads public releases from the GitHub API, unauthenticated (ADR-0027 A4).
type GitHubRelease ¶
type GitHubRelease struct {
Repository string
Name string
Tag string
Version string
Prerelease bool
PublishedAt time.Time
Platforms []string
HasChecksum bool
ChecksumAsset string
// contains filtered or unexported fields
}
GitHubRelease is a release resolved to an exact tag.
type Importer ¶
type Importer struct {
// contains filtered or unexported fields
}
Importer mirrors versions from releases.hashicorp.com and GitHub releases.
func NewImporter ¶
func NewImporter(upstream *Upstream, github *GitHub, keyring openpgp.EntityList, repository Repository) *Importer
NewImporter verifies every releases.hashicorp.com SHA256SUMS against keyring before storing it; GitHub releases carry no key to check.
func (*Importer) ImportGitHubVersion ¶
func (i *Importer) ImportGitHubVersion( ctx context.Context, tenant store.OrganizationTenant, repository, tag string, platforms []string, ) VersionOutcome
ImportGitHubVersion mirrors one public GitHub release's selected platforms. Its signature, if any, is stored verbatim and never verified (ADR-0027 D11).
func (*Importer) ImportVersion ¶
func (i *Importer) ImportVersion( ctx context.Context, tenant store.OrganizationTenant, product, version string, platforms []string, ) VersionOutcome
ImportVersion mirrors one releases.hashicorp.com version's selected platforms. It never returns an error: every failure is the version's recorded outcome.
func (*Importer) Sync ¶
func (i *Importer) Sync(ctx context.Context, tenant store.OrganizationTenant, name string, change store.PluginChange) VersionOutcome
Sync applies one change a publisher made from a plugin's detail page (ADR-0027 A7): add platforms to a version or mirror a new one, or revoke or restore a version.
type Jobs ¶
type Jobs interface {
ClaimPluginImport(context.Context, time.Duration) (*store.ClaimedPluginImport, error)
RecordPluginImport(context.Context, store.OrganizationTenant, uuid.UUID, string, any) error
}
Jobs is where the worker finds and records import jobs.
type PlatformOutcome ¶
type PlatformOutcome struct {
Platform string `json:"platform"`
Outcome string `json:"outcome"`
Error string `json:"error,omitempty"`
}
PlatformOutcome is one requested platform of one version.
type Pruner ¶
type Pruner struct {
// contains filtered or unexported fields
}
Pruner clears finished jobs on each organization's schedule. One organization's run happens on one replica: the claim stamps it run.
type Prunes ¶
type Prunes interface {
Pruning
ClaimPluginPrune(ctx context.Context) (*store.ClaimedPluginPrune, error)
RecordPluginPrune(ctx context.Context, tenant store.OrganizationTenant, cleared int, runErr string, nextAt *time.Time) error
}
Prunes is where the pruner finds due organizations and records runs.
type Pruning ¶
type Pruning interface {
PrunePluginImports(ctx context.Context, tenant store.OrganizationTenant, before time.Time) (int, error)
}
Pruning clears an organization's finished jobs; the API's Prune now and the scheduled pruner share it.
type Repository ¶
type Repository interface {
PublishPluginVersion(context.Context, store.OrganizationTenant, store.PluginVersionInput) error
ListPluginVersions(context.Context, store.OrganizationTenant, string) (store.PluginSource, []store.PluginVersionSummary, error)
GetStoredPluginVersion(ctx context.Context, tenant store.OrganizationTenant, name, version string) (store.StoredPluginVersion, error)
AddPluginZips(ctx context.Context, tenant store.OrganizationTenant, name, version string, zips []store.PluginZip) error
SetPluginVersionRevoked(ctx context.Context, tenant store.OrganizationTenant, name, version string, revoked bool) error
}
Repository is what an import writes through.
type UpdateChecks ¶
type UpdateChecks interface {
ClaimPluginUpdateCheck(ctx context.Context, interval time.Duration, includeGitHub bool) (*store.ClaimedPluginUpdateCheck, error)
RecordPluginUpdateCheck(ctx context.Context, tenant store.OrganizationTenant, id uuid.UUID, latest, tag, checkErr string) error
}
UpdateChecks is where the checker finds due plugins and records results.
type Upstream ¶
type Upstream struct {
// contains filtered or unexported fields
}
Upstream reads HashiCorp's release service: api.releases.hashicorp.com for browsing, releases.hashicorp.com for the files an import fetches.
func NewUpstream ¶
NewUpstream reads the release service at the given base URLs.
type UpstreamVersion ¶
type UpstreamVersion struct {
Version string
Created time.Time
Prerelease bool
State string
Changelog string
Platforms []string
}
UpstreamVersion is one release of a plugin as the release service lists it.
type VersionOutcome ¶
type VersionOutcome struct {
Version string `json:"version"`
Outcome string `json:"outcome"`
Error string `json:"error,omitempty"`
Platforms []PlatformOutcome `json:"platforms,omitempty"`
}
VersionOutcome is one requested version of an import.