github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/cnbutils/registry/search.go (about)

     1  // Package registry provides utilities to search buildpacks using registry API
     2  package registry
     3  
     4  import (
     5  	"encoding/json"
     6  	"fmt"
     7  	"net/http"
     8  
     9  	piperhttp "github.com/SAP/jenkins-library/pkg/http"
    10  	"github.com/SAP/jenkins-library/pkg/log"
    11  )
    12  
    13  const (
    14  	defaultRegistryAPI = "https://registry.buildpacks.io/api/v1/buildpacks"
    15  )
    16  
    17  type latest struct {
    18  	Version string                 `json:"version"`
    19  	Misc    map[string]interface{} `json:"-"`
    20  }
    21  
    22  type version struct {
    23  	Version string `json:"version"`
    24  	Link    string `json:"_link"`
    25  }
    26  
    27  type response struct {
    28  	Latest   latest    `json:"latest"`
    29  	Versions []version `json:"versions"`
    30  }
    31  
    32  type versionResponse struct {
    33  	Addr string                 `json:"addr"`
    34  	Misc map[string]interface{} `json:"-"`
    35  }
    36  
    37  func SearchBuildpack(id, version string, httpClient piperhttp.Sender, baseApiURL string) (string, error) {
    38  	var apiResponse response
    39  
    40  	if baseApiURL == "" {
    41  		baseApiURL = defaultRegistryAPI
    42  	}
    43  
    44  	apiURL := fmt.Sprintf("%s/%s", baseApiURL, id)
    45  
    46  	rawResponse, err := httpClient.SendRequest(http.MethodGet, apiURL, nil, nil, nil)
    47  	if err != nil {
    48  		return "", err
    49  	}
    50  	defer rawResponse.Body.Close()
    51  
    52  	err = json.NewDecoder(rawResponse.Body).Decode(&apiResponse)
    53  	if err != nil {
    54  		return "", fmt.Errorf("unable to parse response from the %s, error: %s", apiURL, err.Error())
    55  	}
    56  
    57  	if version == "" {
    58  		version = apiResponse.Latest.Version
    59  		log.Entry().Infof("Version for the buildpack '%s' is not specified, using the latest '%s'", id, version)
    60  	}
    61  
    62  	for _, ver := range apiResponse.Versions {
    63  		if ver.Version == version {
    64  			return getImageAddr(ver.Link, httpClient)
    65  		}
    66  	}
    67  
    68  	return "", fmt.Errorf("version '%s' was not found for the buildpack '%s'", version, id)
    69  }
    70  
    71  func getImageAddr(link string, httpClient piperhttp.Sender) (string, error) {
    72  	var verResponse versionResponse
    73  
    74  	rawResponse, err := httpClient.SendRequest(http.MethodGet, link, nil, nil, nil)
    75  	if err != nil {
    76  		return "", err
    77  	}
    78  	defer rawResponse.Body.Close()
    79  
    80  	err = json.NewDecoder(rawResponse.Body).Decode(&verResponse)
    81  	if err != nil {
    82  		return "", fmt.Errorf("unable to parse response from the %s, error: %s", link, err.Error())
    83  	}
    84  
    85  	return verResponse.Addr, nil
    86  }