github.com/codefresh-io/kcfi@v0.0.0-20230301195427-c1578715cc46/pkg/helm-internal/monocular/search.go (about)

     1  /*
     2  Copyright The Helm Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package monocular
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"net/http"
    23  	"net/url"
    24  	"path"
    25  	"time"
    26  
    27  	//"helm.sh/helm/v3/internal/version"
    28  	"github.com/codefresh-io/kcfi/pkg/helm-internal/version"
    29  	"helm.sh/helm/v3/pkg/chart"
    30  )
    31  
    32  // SearchPath is the url path to the search API in monocular.
    33  const SearchPath = "api/chartsvc/v1/charts/search"
    34  
    35  // The structs below represent the structure of the response from the monocular
    36  // search API. The structs were not imported from monocular because monocular
    37  // imports from Helm v2 (avoiding circular version dependency) and the mappings
    38  // are slightly different (monocular search results do not directly reflect
    39  // the struct definitions).
    40  
    41  // SearchResult represents an individual chart result
    42  type SearchResult struct {
    43  	ID            string        `json:"id"`
    44  	Type          string        `json:"type"`
    45  	Attributes    Chart         `json:"attributes"`
    46  	Links         Links         `json:"links"`
    47  	Relationships Relationships `json:"relationships"`
    48  }
    49  
    50  // Chart is the attributes for the chart
    51  type Chart struct {
    52  	Name        string             `json:"name"`
    53  	Repo        Repo               `json:"repo"`
    54  	Description string             `json:"description"`
    55  	Home        string             `json:"home"`
    56  	Keywords    []string           `json:"keywords"`
    57  	Maintainers []chart.Maintainer `json:"maintainers"`
    58  	Sources     []string           `json:"sources"`
    59  	Icon        string             `json:"icon"`
    60  }
    61  
    62  // Repo contains the name in monocular the url for the repository
    63  type Repo struct {
    64  	Name string `json:"name"`
    65  	URL  string `json:"url"`
    66  }
    67  
    68  // Links provides a set of links relative to the chartsvc base
    69  type Links struct {
    70  	Self string `json:"self"`
    71  }
    72  
    73  // Relationships provides information on the latest version of the chart
    74  type Relationships struct {
    75  	LatestChartVersion LatestChartVersion `json:"latestChartVersion"`
    76  }
    77  
    78  // LatestChartVersion provides the details on the latest version of the chart
    79  type LatestChartVersion struct {
    80  	Data  ChartVersion `json:"data"`
    81  	Links Links        `json:"links"`
    82  }
    83  
    84  // ChartVersion provides the specific data on the chart version
    85  type ChartVersion struct {
    86  	Version    string    `json:"version"`
    87  	AppVersion string    `json:"app_version"`
    88  	Created    time.Time `json:"created"`
    89  	Digest     string    `json:"digest"`
    90  	Urls       []string  `json:"urls"`
    91  	Readme     string    `json:"readme"`
    92  	Values     string    `json:"values"`
    93  }
    94  
    95  // Search performs a search against the monocular search API
    96  func (c *Client) Search(term string) ([]SearchResult, error) {
    97  
    98  	// Create the URL to the search endpoint
    99  	// Note, this is currently an internal API for the Hub. This should be
   100  	// formatted without showing how monocular operates.
   101  	p, err := url.Parse(c.BaseURL)
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  
   106  	// Set the path to the monocular API endpoint for search
   107  	p.Path = path.Join(p.Path, SearchPath)
   108  
   109  	p.RawQuery = "q=" + url.QueryEscape(term)
   110  
   111  	// Create request
   112  	req, err := http.NewRequest("GET", p.String(), nil)
   113  	if err != nil {
   114  		return nil, err
   115  	}
   116  
   117  	// Set the user agent so that monocular can identify where the request
   118  	// is coming from
   119  	req.Header.Set("User-Agent", version.GetUserAgent())
   120  
   121  	res, err := http.DefaultClient.Do(req)
   122  	if err != nil {
   123  		return nil, err
   124  	}
   125  	defer res.Body.Close()
   126  
   127  	if res.StatusCode != 200 {
   128  		return nil, fmt.Errorf("failed to fetch %s : %s", p.String(), res.Status)
   129  	}
   130  
   131  	result := &searchResponse{}
   132  
   133  	json.NewDecoder(res.Body).Decode(result)
   134  
   135  	return result.Data, nil
   136  }
   137  
   138  type searchResponse struct {
   139  	Data []SearchResult `json:"data"`
   140  }