mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-07-30 00:27:56 +00:00
Signed-off-by: Andrew Borg <andrew.b.borg@gmail.com> Co-authored-by: PePe Amengual <2208324+jamengual@users.noreply.github.com> Co-authored-by: Simon Heather <32168619+X-Guardian@users.noreply.github.com>
142 lines
3.4 KiB
Go
142 lines
3.4 KiB
Go
package terraform
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sort"
|
|
|
|
"github.com/hashicorp/go-version"
|
|
"github.com/hashicorp/hc-install/product"
|
|
"github.com/hashicorp/hc-install/releases"
|
|
"github.com/opentofu/tofudl"
|
|
)
|
|
|
|
type Distribution interface {
|
|
BinName() string
|
|
Downloader() Downloader
|
|
// ResolveConstraint gets the latest version for the given constraint
|
|
ResolveConstraint(context.Context, string) (*version.Version, error)
|
|
}
|
|
|
|
func NewDistribution(distribution string) Distribution {
|
|
tfDistribution := NewDistributionTerraform()
|
|
if distribution == "opentofu" {
|
|
tfDistribution = NewDistributionOpenTofu()
|
|
}
|
|
return tfDistribution
|
|
}
|
|
|
|
type DistributionOpenTofu struct {
|
|
downloader Downloader
|
|
}
|
|
|
|
func NewDistributionOpenTofu() Distribution {
|
|
return &DistributionOpenTofu{
|
|
downloader: &TofuDownloader{},
|
|
}
|
|
}
|
|
|
|
func NewDistributionOpenTofuWithDownloader(downloader Downloader) Distribution {
|
|
return &DistributionOpenTofu{
|
|
downloader: downloader,
|
|
}
|
|
}
|
|
|
|
func (*DistributionOpenTofu) BinName() string {
|
|
return "tofu"
|
|
}
|
|
|
|
func (d *DistributionOpenTofu) Downloader() Downloader {
|
|
return d.downloader
|
|
}
|
|
|
|
func (*DistributionOpenTofu) ResolveConstraint(ctx context.Context, constraintStr string) (*version.Version, error) {
|
|
dl, err := tofudl.New()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
vc, err := version.NewConstraint(constraintStr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error parsing constraint string: %s", err)
|
|
}
|
|
|
|
allVersions, err := dl.ListVersions(ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error listing OpenTofu versions: %s", err)
|
|
}
|
|
|
|
var versions []*version.Version
|
|
for _, ver := range allVersions {
|
|
v, err := version.NewVersion(string(ver.ID))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if vc.Check(v) {
|
|
versions = append(versions, v)
|
|
}
|
|
}
|
|
sort.Sort(version.Collection(versions))
|
|
|
|
if len(versions) == 0 {
|
|
return nil, fmt.Errorf("no OpenTofu versions found for constraints %s", constraintStr)
|
|
}
|
|
|
|
// We want to select the highest version that satisfies the constraint.
|
|
version := versions[len(versions)-1]
|
|
|
|
// Get the Version object from the versionDownloader.
|
|
return version, nil
|
|
}
|
|
|
|
type DistributionTerraform struct {
|
|
downloader Downloader
|
|
}
|
|
|
|
func NewDistributionTerraform() Distribution {
|
|
return &DistributionTerraform{
|
|
downloader: &TerraformDownloader{},
|
|
}
|
|
}
|
|
|
|
func NewDistributionTerraformWithDownloader(downloader Downloader) Distribution {
|
|
return &DistributionTerraform{
|
|
downloader: downloader,
|
|
}
|
|
}
|
|
|
|
func (*DistributionTerraform) BinName() string {
|
|
return "terraform"
|
|
}
|
|
|
|
func (d *DistributionTerraform) Downloader() Downloader {
|
|
return d.downloader
|
|
}
|
|
|
|
func (*DistributionTerraform) ResolveConstraint(ctx context.Context, constraintStr string) (*version.Version, error) {
|
|
vc, err := version.NewConstraint(constraintStr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error parsing constraint string: %s", err)
|
|
}
|
|
|
|
constrainedVersions := &releases.Versions{
|
|
Product: product.Terraform,
|
|
Constraints: vc,
|
|
}
|
|
|
|
installCandidates, err := constrainedVersions.List(ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error listing available versions: %s", err)
|
|
}
|
|
if len(installCandidates) == 0 {
|
|
return nil, fmt.Errorf("no Terraform versions found for constraints %s", constraintStr)
|
|
}
|
|
|
|
// We want to select the highest version that satisfies the constraint.
|
|
versionDownloader := installCandidates[len(installCandidates)-1]
|
|
|
|
// Get the Version object from the versionDownloader.
|
|
return versionDownloader.(*releases.ExactVersion).Version, nil
|
|
}
|