Skip to content

Commit

Permalink
Get latest HashiCorp releases
Browse files Browse the repository at this point in the history
Related to #560

In case a tool has a `URLTemplate` including
https://releases.hashicorp.com ,
it will fetch its latest release via the
https://checkpoint.hashicorp.com API.

At the moment, `terraform`, `vagrant`, and `packer` are being supported.

Signed-off-by: Yuval Goldberg <yuvigoldi@gmail.com>
  • Loading branch information
YuviGold committed Aug 15, 2022
1 parent 60c9bdc commit 0104fa3
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 15 deletions.
79 changes: 67 additions & 12 deletions pkg/get/get.go
Expand Up @@ -3,8 +3,10 @@ package get
import (
"bytes"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"net"
Expand All @@ -22,6 +24,15 @@ var supportedArchitectures = [...]string{"x86_64", "arm", "amd64", "armv6l", "ar
// githubTimeout expanded from the original 5 seconds due to #693
var githubTimeout = time.Second * 10

type HashiCorpProduct struct {
Product string `json:"product"`
CurrentVersion string `json:"current_version"`
CurrentRelease int `json:"current_release"`
CurrentDownloadURL string `json:"current_download_url"`
CurrentChangelogURL string `json:"current_changelog_url"`
ProjectWebsite string `json:"project_website"`
}

// Tool describes how to download a CLI tool from a binary
// release - whether a single binary, or an archive.
type Tool struct {
Expand Down Expand Up @@ -126,20 +137,34 @@ func (tool Tool) Head(uri string) (int, string, http.Header, error) {

func (tool Tool) GetURL(os, arch, version string, quiet bool) (string, error) {

if len(version) == 0 &&
(len(tool.URLTemplate) == 0 || strings.Contains(tool.URLTemplate, "https://github.com/")) {
if !quiet {
log.Printf("Looking up version for %s", tool.Name)
}
if len(version) == 0 {
if len(tool.URLTemplate) == 0 || strings.Contains(tool.URLTemplate, "https://github.com/") {
if !quiet {
log.Printf("Looking up version for %s on GitHub", tool.Name)
}

v, err := FindGitHubRelease(tool.Owner, tool.Repo)
if err != nil {
return "", err
}
if !quiet {
log.Printf("Found: %s", v)
v, err := FindGitHubRelease(tool.Owner, tool.Repo)
if err != nil {
return "", err
}
if !quiet {
log.Printf("Found: %s", v)
}
version = v
} else if strings.Contains(tool.URLTemplate, "https://releases.hashicorp.com") {
if !quiet {
log.Printf("Looking up version for %s on HashiCorp", tool.Name)
}

v, err := FindHashiCorpRelease(tool.Name)
if err != nil {
return "", err
}
if !quiet {
log.Printf("Found: %s", v)
}
version = v
}
version = v
}

if len(tool.URLTemplate) > 0 {
Expand Down Expand Up @@ -213,6 +238,36 @@ func FindGitHubRelease(owner, repo string) (string, error) {
return version, nil
}

func FindHashiCorpRelease(name string) (string, error) {
url := fmt.Sprintf("https://checkpoint-api.hashicorp.com/v1/check/%s", name)
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return "", err
}

res, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
}

if res.StatusCode != http.StatusOK {
return "", fmt.Errorf("unexpected status code: %d", res.StatusCode)
}
if res.Body == nil {
return "", fmt.Errorf("unexpected empty body")
}

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

var product HashiCorpProduct
if err = json.Unmarshal(body, &product); err != nil {
return "", err
}

return product.CurrentVersion, nil
}

func getBinaryURL(owner, repo, version, downloadName string) string {
if in := strings.Index(downloadName, "/"); in > -1 {
return fmt.Sprintf(
Expand Down
3 changes: 0 additions & 3 deletions pkg/get/tools.go
Expand Up @@ -659,7 +659,6 @@ https://github.com/inlets/inletsctl/releases/download/{{.Version}}/{{$fileName}}
Owner: "hashicorp",
Repo: "terraform",
Name: "terraform",
Version: "1.1.9",
Description: "Infrastructure as Code for major cloud providers.",
URLTemplate: `
{{$arch := ""}}
Expand Down Expand Up @@ -717,7 +716,6 @@ https://github.com/inlets/inletsctl/releases/download/{{.Version}}/{{$fileName}}
Owner: "hashicorp",
Repo: "vagrant",
Name: "vagrant",
Version: "2.2.19",
Description: "Tool for building and distributing development environments.",
URLTemplate: `{{$arch := .Arch}}
Expand All @@ -739,7 +737,6 @@ https://releases.hashicorp.com/{{.Name}}/{{.Version}}/{{.Name}}_{{.Version}}_{{$
Owner: "hashicorp",
Repo: "packer",
Name: "packer",
Version: "1.8.0",
Description: "Build identical machine images for multiple platforms from a single source configuration.",
URLTemplate: `
{{$arch := ""}}
Expand Down

0 comments on commit 0104fa3

Please sign in to comment.