136 lines
3.9 KiB
Go
136 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"sort"
|
|
"strings"
|
|
|
|
s3 "github.com/minio/minio-go/v7"
|
|
)
|
|
|
|
func router(w http.ResponseWriter, r *http.Request) {
|
|
path := strings.TrimPrefix(r.URL.Path, "/v1/providers/")
|
|
parts := strings.Split(path, "/")
|
|
|
|
if len(parts) == 3 && parts[2] == "versions" {
|
|
listVersions(w, parts[0], parts[1])
|
|
return
|
|
}
|
|
|
|
if len(parts) == 6 && parts[3] == "download" {
|
|
downloadVersion(w, parts[0], parts[1], parts[2], parts[4], parts[5])
|
|
return
|
|
}
|
|
|
|
http.Error(w, "Not Found", http.StatusNotFound)
|
|
}
|
|
|
|
func listVersions(w http.ResponseWriter, namespace, pType string) {
|
|
prefix := fmt.Sprintf("%s/%s/%s/", s3Prefix, namespace, pType)
|
|
versions := []Version{}
|
|
seenVersions := map[string]*Version{}
|
|
|
|
objectCh := s3Client.ListObjects(context.Background(), bucketName, s3.ListObjectsOptions{
|
|
Prefix: prefix,
|
|
Recursive: true,
|
|
})
|
|
|
|
for object := range objectCh {
|
|
if object.Err != nil {
|
|
continue
|
|
}
|
|
parts := strings.Split(object.Key, "/")
|
|
if len(parts) < 5 {
|
|
continue
|
|
}
|
|
verStr := parts[3]
|
|
fileName := parts[4]
|
|
|
|
if _, ok := seenVersions[verStr]; !ok {
|
|
seenVersions[verStr] = &Version{
|
|
Version: verStr,
|
|
Protocols: []string{"5.0"},
|
|
Platforms: []Platform{},
|
|
}
|
|
}
|
|
|
|
if strings.Contains(fileName, "_darwin_amd64.zip") {
|
|
seenVersions[verStr].Platforms = append(seenVersions[verStr].Platforms, Platform{OS: "darwin", Arch: "amd64"})
|
|
}
|
|
if strings.Contains(fileName, "_linux_amd64.zip") {
|
|
seenVersions[verStr].Platforms = append(seenVersions[verStr].Platforms, Platform{OS: "linux", Arch: "amd64"})
|
|
}
|
|
if strings.Contains(fileName, "_windows_amd64.zip") {
|
|
seenVersions[verStr].Platforms = append(seenVersions[verStr].Platforms, Platform{OS: "windows", Arch: "amd64"})
|
|
}
|
|
}
|
|
|
|
for _, v := range seenVersions {
|
|
versions = append(versions, *v)
|
|
}
|
|
|
|
sort.Slice(versions, func(i, j int) bool {
|
|
return versions[i].Version < versions[j].Version
|
|
})
|
|
|
|
resp := VersionList{
|
|
ID: fmt.Sprintf("%s/%s", namespace, pType),
|
|
Versions: versions,
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(resp)
|
|
}
|
|
|
|
func downloadVersion(w http.ResponseWriter, namespace, pType, version, osType, arch string) {
|
|
basePath := fmt.Sprintf("%s/%s/%s/%s", s3Prefix, namespace, pType, version)
|
|
filename := fmt.Sprintf("terraform-provider-%s_%s_%s_%s.zip", pType, version, osType, arch)
|
|
fullKey := fmt.Sprintf("%s/%s", basePath, filename)
|
|
shasumsKey := fmt.Sprintf("%s/terraform-provider-%s_%s_SHA256SUMS", basePath, pType, version)
|
|
sigKey := fmt.Sprintf("%s/terraform-provider-%s_%s_SHA256SUMS.sig", basePath, pType, version)
|
|
|
|
var shasumValue string
|
|
shasumsObj, err := s3Client.GetObject(context.Background(), bucketName, shasumsKey, s3.GetObjectOptions{})
|
|
if err == nil {
|
|
defer shasumsObj.Close()
|
|
scanner := bufio.NewScanner(shasumsObj)
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
if strings.Contains(line, filename) {
|
|
fields := strings.Fields(line)
|
|
if len(fields) >= 1 {
|
|
shasumValue = fields[0]
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
baseURL := "https://" + hostname
|
|
downloadLink := fmt.Sprintf("%s/v1/proxy?bucket=%s&key=%s", baseURL, bucketName, url.QueryEscape(fullKey))
|
|
shasumsLink := fmt.Sprintf("%s/v1/proxy?bucket=%s&key=%s", baseURL, bucketName, url.QueryEscape(shasumsKey))
|
|
sigLink := fmt.Sprintf("%s/v1/proxy?bucket=%s&key=%s", baseURL, bucketName, url.QueryEscape(sigKey))
|
|
|
|
resp := DownloadResponse{
|
|
Protocols: []string{"5.0"},
|
|
OS: osType,
|
|
Arch: arch,
|
|
Filename: filename,
|
|
DownloadURL: downloadLink,
|
|
ShasumsURL: shasumsLink,
|
|
ShasumsSignatureURL: sigLink,
|
|
Shasum: shasumValue,
|
|
SigningKeys: SigningKeys{
|
|
GPGPublicKeys: []GPGPublicKey{gpgPrimaryKey, gpgLegacyKey},
|
|
},
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(resp)
|
|
}
|